Current best version

Figure 1 - This figures shows…

Figure 1 - This figures shows…

Code

  1. R environment setup
  2. Setting time breaks
  3. Defining origins
  4. Import raster data
  5. GAM smoothing models
  6. Compare rates between origins and not-origins
  7. Compare rates between different time periods
  8. Setup final figure
  9. Map for final figure
  10. Trend through time panel for final figure
  11. Assemble and print final figure

R environment setup

Attach libraries

library(png)
library(maptools)
Checking rgeos availability: TRUE
library(raster)
library(gam)
Loading required package: splines
Loading required package: foreach
foreach: simple, scalable parallel programming from Revolution Analytics
Use Revolution R for scalability, fault tolerance and more.
http://www.revolutionanalytics.com
Loaded gam 1.14
library(mapproj)
Loading required package: maps
library(rgl)

Set working directory

setwd("~/Desktop/Botero postdoc 2016/Human density and the origins of agriculture/")

Setting time breaks

Define the times of agricultural origins

par(mar=c(0,0,0,20))
d <- readPNG("Larson_dates.png")
plot(seq(0,18, length.out = 19), seq(0,36, length.out = 19), type="n",ylim=c(0,36),xlim=c(0, 18), xaxt="n")
rasterImage(d, 0,0,18,36, interpolate=TRUE, col=d)
Start_of_early_window <- 16-12
End_of_early_window_start_of_late_window <- 8.2
End_of_late_window <- 17-4.2
polygon(x=c(Start_of_early_window, Start_of_early_window, End_of_early_window_start_of_late_window, End_of_early_window_start_of_late_window), y=c(0, 34, 34, 0), col=adjustcolor("limegreen", alpha= 0.2), border=adjustcolor("limegreen", alpha= 0.9))
polygon(x=c( End_of_early_window_start_of_late_window, End_of_early_window_start_of_late_window, End_of_late_window, End_of_late_window), y=c(0, 34, 34, 0), col=adjustcolor("firebrick", alpha= 0.2), border=adjustcolor("firebrick", alpha= 0.9))

These dates are provided in the supplimentary information for the Larson (2014) paper. I’ve copied those values into a .csv table provided here.

domestication_times <- read.csv("Domestication timing larson 2014.csv")
dim(domestication_times)
[1] 77  8
Region Species Start.Exploitation Finish.Exploitation Start.predomestication Finish.predomestication Start.Domestication Finish.Domestication
Southwest asia Wheat 12.00 11.25 11.25 11.00 11.00 9.00
Southwest asia Barley 12.00 11.25 11.25 10.50 10.50 9.00
Southwest asia Lentil 12.00 11.00 11.00 10.50 10.50 9.00
Southwest asia Pea 11.50 11.00 11.00 10.00 10.00 8.50
Southwest asia Chickpea 11.00 10.50 10.50 10.25 10.25 8.25
Southwest asia Broadbean NA NA NA NA 10.50 NA
Southwest asia Flax 12.00 9.50 NA NA 9.50 NA
Southwest asia Olive 10.00 6.00 NA NA 6.00 NA
Southwest asia Sheep 12.00 10.50 10.50 9.75 9.75 8.00
Southwest asia Goat 12.00 10.50 10.50 9.75 9.75 8.00
Southwest asia Pig 12.00 11.50 11.50 9.75 10.25 9.00
Southwest asia Cattle, taurine 11.50 10.50 10.50 10.25 10.25 8.00
Southwest asia Cat NA NA 10.50 4.00 4.00 NA
South Asia Tree cotton 8.50 4.50 NA NA 4.50 NA
South Asia Rice 8.00 5.00 5.00 4.00 4.00 2.50
South Asia Little millet NA NA NA NA 4.50 NA
South Asia Browntop millet NA NA NA NA 4.00 NA
South Asia Mungbean NA NA 4.50 3.50 3.50 3.00
South Asia Pigeonpea NA NA NA NA 3.50 NA
South Asia Zebu cattle 9.00 8.00 NA NA 8.00 6.50
South Asia Water buffalo 6.00 4.50 NA NA 4.50 NA
East Asia Broomcorn Millet 10.00 8.00 NA NA 8.00 NA
East Asia Foxtail millet 11.50 7.50 NA NA 7.50 NA
East Asia Rice 10.00 8.00 8.00 7.50 7.50 5.00
East Asia Soybean 8.50 5.50 NA NA 5.50 4.00
East Asia Ramie NA NA NA NA 5.25 NA
East Asia Melon 7.00 4.00 NA NA 4.00 3.75
East Asia Pig 12.00 8.50 NA NA 8.50 6.00
East Asia Silkworm 7.00 5.25 NA NA 5.25 NA
East Asia Yak NA NA NA NA 4.25 NA
East Asia Horse 7.50 6.75 6.75 5.50 5.50 4.00
East Asia Bactrian Camel NA NA NA NA 4.50 NA
East Asia Duck 2.50 1.00 NA NA 1.00 NA
East Asia Chicken 6.00 4.00 NA NA 4.00 NA
New Guinea Banana 10.00 7.00 7.00 4.00 4.00 NA
New Guinea Taro 10.00 7.00 7.00 4.00 NA NA
New Guinea Yam 10.00 7.00 7.00 4.00 NA NA
Africa and Arabia Date palm 7.00 6.00 NA NA 5.00 NA
Africa and Arabia Sorghum 8.00 4.00 NA NA 4.00 NA
Africa and Arabia Pearl millet NA NA NA NA 4.50 3.50
Africa and Arabia Fonio NA NA NA NA 2.50 NA
Africa and Arabia Cowpea NA NA NA NA 3.75 NA
Africa and Arabia Hyacinth bean NA NA NA NA 3.75 NA
Africa and Arabia Rice 3.50 2.00 NA NA 2.00 NA
Africa and Arabia Oil palm 9.25 3.50 NA NA 3.50 NA
Africa and Arabia Cattle NA NA 9.00 7.75 7.75 6.50
Africa and Arabia Donkey 9.00 5.50 NA NA 5.50 3.50
Africa and Arabia Dromedary camel 6.50 3.00 NA NA 3.00 NA
Africa and Arabia Guinea fowl NA NA 2.50 1.50 1.50 NA
North America Squash 6.50 5.00 NA NA 5.00 NA
North America Sunflower 6.00 4.75 NA NA 4.00 NA
North America Sumpweed 6.00 4.50 NA NA 4.00 NA
North America Pitseed goosefoot 4.75 3.75 NA NA 3.75 NA
Meso-america Squash (pepo) NA NA NA NA 10.00 9.50
Meso-america Maize 10.00 9.00 NA NA 9.00 NA
Meso-america Foxtail millet-grass NA NA NA NA 6.00 4.00
Meso-america Common bean NA NA NA NA 3.00 NA
Meso-america Avocado NA NA NA NA 3.00 NA
Meso-america Chile pepper NA NA NA NA 3.00 NA
Meso-america Turkey NA NA NA NA 2.00 NA
South America Chili pepper NA NA NA NA 6.00 NA
South America Peanut NA NA NA NA 5.00 NA
South America Cotton NA NA NA NA 6.00 NA
South America Coca NA NA NA NA 8.00 NA
South America Now-minor root crops (arrowroot, leren) NA NA NA NA 9.00 NA
South America Squash NA NA NA NA 10.00 NA
South America Common bean NA NA NA NA 5.00 NA
South America Lima bean NA NA 8.25 NA 6.00 NA
South America Monioc NA NA NA NA 7.00 NA
South America Sweet potato NA NA NA NA 5.00 NA
South America White potato 7.00 4.50 NA NA 4.00 NA
South America Quinoa 5.00 NA NA NA 3.50 NA
South America Yam NA NA NA NA 5.50 NA
South America Llama 10.00 6.00 NA NA 6.00 NA
South America Alpaca 10.00 5.00 NA NA 5.00 NA
South America Guinea pig NA NA NA NA 5.00 NA
South America Muscovy Duck NA NA NA NA 4.00 NA
par(mar=c(5,4,6,1))
dates <- unlist(domestication_times[3:8])
hist(dates, breaks = 22, xlim=c(15,0), xlab="K years ago", col=adjustcolor("cornflowerblue", alpha= 0.5), border=adjustcolor("cornflowerblue", alpha= 0.9), main="All dates in dataset"  )
mtext("This tells us about how evenly our evidence is distributed in time", 3, line=1)

hist(dates, breaks = 22, xlim=c(15,0), xlab="Thousand years ago", col=adjustcolor("cornflowerblue", alpha= 0.5), border=adjustcolor("cornflowerblue", alpha= 0.9), main="All dates in dataset with Larson(2014) date windows")
Start_of_early_window <- 12
End_of_early_window_start_of_late_window <- 8.2
End_of_late_window <- 4.2
polygon(x=c(Start_of_early_window, Start_of_early_window, End_of_early_window_start_of_late_window, End_of_early_window_start_of_late_window), y=c(0, 30, 30, 0), col=adjustcolor("limegreen", alpha= 0.2), border=adjustcolor("limegreen", alpha= 0.9))
polygon(x=c( End_of_early_window_start_of_late_window, End_of_early_window_start_of_late_window, End_of_late_window, End_of_late_window), y=c(0, 30, 30, 0), col=adjustcolor("firebrick", alpha= 0.2), border=adjustcolor("firebrick", alpha= 0.9))
hist(dates, breaks = 22, xlim=c(15,0), xlab="K years ago", col=adjustcolor("cornflowerblue", alpha= 0.2), border=adjustcolor("cornflowerblue", alpha= 0.9), main="", add=TRUE)
mtext("Early Holocene", 3, line = -1, adj=.3)
mtext("Middle Holocene", 3, line= -1, adj=.6)

par(mfrow=c(2,3), mar=c(4,4,2,0))
dim(domestication_times)
[1] 77  8
specific_dates <- domestication_times[,3:8]
for(i in c(1, 3, 5, 2, 4, 6)){
hist(specific_dates[,i], breaks = 22, xlim=c(15,0), xlab="Thousand years ago", col=adjustcolor("cornflowerblue", alpha= 0.5), border=adjustcolor("cornflowerblue", alpha= 0.9), main= names(specific_dates)[i])
Start_of_early_window <- 12
End_of_early_window_start_of_late_window <- 8.2
End_of_late_window <- 4.2
polygon(x=c(Start_of_early_window, Start_of_early_window, End_of_early_window_start_of_late_window, End_of_early_window_start_of_late_window), y=c(0, 30, 30, 0), col=adjustcolor("limegreen", alpha= 0.2), border=adjustcolor("limegreen", alpha= 0.9))
polygon(x=c( End_of_early_window_start_of_late_window, End_of_early_window_start_of_late_window, End_of_late_window, End_of_late_window), y=c(0, 30, 30, 0), col=adjustcolor("firebrick", alpha= 0.2), border=adjustcolor("firebrick", alpha= 0.9))
hist(specific_dates[,i], breaks = 22, xlim=c(15,0), xlab="K years ago", col=adjustcolor("cornflowerblue", alpha= 0.2), border=adjustcolor("cornflowerblue", alpha= 0.9), main="", add=TRUE)
}

I’m creating new rows for this table, combining dates in different ways to make the CDFs below look more authentic. This makes it so that pre-ag always happens before post-ag. What I’ve done is given the later date to the earlier date when those dates are missing.

h <- which(is.na(domestication_times[,3]))
domestication_times <- cbind(domestication_times, rep(NA, length(domestication_times[,1])))
domestication_times[,9] <- domestication_times[,3]
domestication_times[h,9] <- domestication_times[h,7]
colnames(domestication_times)[9] <- "adopt exploitation date"
domestication_times[,10] <- domestication_times[,7]
domestication_times[which(is.na(domestication_times[,10])),10] <- 0
colnames(domestication_times)[10] <- "start of ag"
#save(domestication_times, file="~/Desktop/Human density and the origins of agriculture/Domestication timing larson 2014.Rdata")

I think these are best described by a cummulative distribution, showing how they accumulate over time.

for(i in 1:8){
type_number <- i
    match <- domestication_times[ which(domestication_times$Region == levels(domestication_times$Region)[ type_number]), 9]
    maxer <- max(match, na.rm=TRUE)
    j <- ecdf(maxer-match)
    print(levels(domestication_times$Region)[ type_number])
    print(match)
    print(j)
}
[1] "Africa and Arabia"
 [1] 7.00 8.00 4.50 2.50 3.75 3.75 3.50 9.25 7.75 9.00 6.50 1.50
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:11] =      0,   0.25,   1.25,  ...,   6.75,   7.75
[1] "East Asia"
 [1] 10.00 11.50 10.00  8.50  5.25  7.00 12.00  7.00  4.25  7.50  4.50  2.50  6.00
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:11] =      0,    0.5,      2,  ...,   7.75,    9.5
[1] "Meso-america"
[1] 10 10  6  3  3  3  2
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:4] =      0,      4,      7,      8
[1] "New Guinea"
[1] 10 10 10
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:1] =      0
[1] "North America"
[1] 6.50 6.00 6.00 4.75
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:3] =      0,    0.5,   1.75
[1] "South America"
 [1]  6.0  5.0  6.0  8.0  9.0 10.0  5.0  6.0  7.0  5.0  7.0  5.0  5.5 10.0 10.0  5.0  4.0
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:8] =      0,      1,      2,  ...,      5,      6
[1] "South Asia"
[1] 8.5 8.0 4.5 4.0 3.5 3.5 9.0 6.0
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:7] =      0,    0.5,      1,  ...,      5,    5.5
[1] "Southwest asia"
 [1] 12.0 12.0 12.0 11.5 11.0 10.5 12.0 10.0 12.0 12.0 12.0 11.5  4.0
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:6] =      0,    0.5,      1,  ...,      2,      8
par(mfcol=c(2,5), mar=c(4,0,5,0))
plot(0,0, type="n", xaxt="n", xlab="", bty="n")
mtext("Percent of species that will eventually \n be domesticated in a region", 2, line=-5, cex=0.5)
plot(0,0, type="n", xaxt="n", xlab="", bty="n")
mtext("Percent of species that will eventually \n be domesticated in a region", 2, line=-5, cex=0.5)
for(i in 1:8){
type_number <- i
    match <- domestication_times[ which(domestication_times$Region == levels(domestication_times$Region)[ type_number]), 9]
    maxer <- max(match, na.rm=TRUE)
    j <- ecdf(maxer-match)
    #print(j)
    
plot(0,0, xlim=c(15,0), ylim=c(0,100), ylab="Percent of species that will eventually \n be domesticated in a region", xlab="Thousand years ago", main=levels(domestication_times$Region)[ type_number], type="n", yaxt="n")
x_seq <- rev(c(0,seq(0, maxer, length.out=100)))
y_seq <- 100 * (c(0, j(seq(0, maxer, length.out=100))))
lines(x_seq, y_seq,  ylim=c(-1,1))
polygon(c(0, x_seq), c(0, y_seq), border=adjustcolor("cornflowerblue",alpha=1), col=adjustcolor("cornflowerblue", alpha=0.2))
if(i == 2 | i == 1)axis(2)
if(i == 3)mtext("Cummulative distribution function for the accumulation of domesticates", 3, line=3.8, col="cornflowerblue")
}

par(mfcol=c(2,5), mar=c(4,0,5,0))
plot(0,0, type="n", xaxt="n", xlab="", bty="n")
mtext("Percent of species that will eventually \n be domesticated in a region", 2, line=-5, cex=0.5)
plot(0,0, type="n", xaxt="n", xlab="", bty="n")
mtext("Percent of species that will eventually \n be domesticated in a region", 2, line=-5, cex=0.5)
for(i in 1:8){
type_number <- i
    match <- domestication_times[ which(domestication_times$Region == levels(domestication_times$Region)[ type_number]), 9]
    maxer <- max(match, na.rm=TRUE)
    j <- ecdf(maxer-match)
    #print(j)
    
plot(0,0, xlim=c(15,0), ylim=c(0,100), ylab="Percent of species that will eventually \n be domesticated in a region", xlab="Thousand years ago", main=levels(domestication_times$Region)[ type_number], type="n", yaxt="n")
x_seq <- rev(c(0,seq(0, maxer, length.out=100)))
y_seq <- 100 * (c(0, j(seq(0, maxer, length.out=100))))
lines(x_seq, y_seq,  ylim=c(-1,1))
polygon(c(0, x_seq), c(0, y_seq), border=adjustcolor("cornflowerblue",alpha=1), col=adjustcolor("cornflowerblue", alpha=0.2))
abline(v= maxer - quantile(j)[2], col="limegreen", lwd=2)
if(i == 2 | i == 1)axis(2)
if(i == 2)mtext("25%", 3, line=3.5, adj=-1, col="limegreen")
if(i == 3)mtext("Cummulative distribution function for the accumulation of domesticates", 3, line=3.8, col="cornflowerblue")
if(i == 4)mtext("Choose a y to predict an x", 3, line=3.3, col="cornflowerblue")
    break_one <- maxer
            break_two <- maxer - quantile(j)[2]
                
    polygon(x=c(break_two, break_two, break_one, break_one), y=c(0, 1, 1, 0), col=adjustcolor("cornflowerblue", alpha=0.2), border=adjustcolor("cornflowerblue",alpha=1))
            lines(x=c(break_two, break_two), y=c(0,-1), col="cornflowerblue")
            abline(h = 25, col="limegreen", lwd=2)
}

Make this a function. There is a choice of two methods here. At the end of this section we need to print the desision we’re passing to the later analyses.

Defining origins

library(maps)
map()
map(origins, add=TRUE, fill=TRUE, col=adjustcolor("cornflowerblue", alpha=1))
database does not (uniquely) contain the field 'name'.

map()
d <- readPNG("Larson_origins.png")
rasterImage(d, -180, -90, 180, 110, interpolate=TRUE, col=d)
map(add=TRUE)
map(origins, add=TRUE, fill=TRUE, col=adjustcolor("cornflowerblue", alpha=1))
database does not (uniquely) contain the field 'name'.

# need to reproject

This is obviously a bad projection fit right now.

map for final figure

origins <- readShapePoly('Origins_updated.shp')
proj4string(origins) <- CRS("+proj=longlat +datum=WGS84")
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
#proj <- CRS("+proj=eqc +lat_ts=0 +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +units=m +no_defs")
#origins.ea <- spTransform(origins, proj)
#subset_order <- c(1, 2, 3, 5, 6, 8, 9, 10, 11, 12, 17, 18)
subset_order <- c(8, 10, 9, 5, 18, 7, 6, 20, 1, 2, 13, 14)
origins_subset <- origins[subset_order,]
origins_subset$CONTINENT
 [1] Mesoamerica   NW_Lowland_SA N_Lowland_SA  Fertile_Cresc Chinese_loess New_Guinea   
 [7] E_North_Ameri C/S_Andes     W_African_Sav Sudanic_Savan Ganges_E_Indi Lower-MiddleY
20 Levels: C/S_Andes Chinese_loess E_North_Ameri Ethipian plat Fertile_Cresc ... West Africa T
origins_subset$name
NULL

Make the map for the center panel (#5 on layout panel)

d <- readPNG("earth.png")
png(file=paste("40962.png",sep=""),width=2000,height=1000, bg="transparent")
par(mar=c(0,0,0,0))
plot(seq(-180, 180, length.out = 19), seq(-90, 90, length.out = 19), type="n",xlim=c(-180, 180),ylim=c(-90, 90), xaxt="n")
rasterImage(d, -180, -90, 180, 90, interpolate=TRUE, col=d)
polygon(x=c(-180,-180, 180,180), y=c(-90, 90, 90, -90), col=adjustcolor("white", alpha=0.1))
#rasterImage(d, -13.5, -13.5, 375, 375, interpolate=TRUE, col=d)
plot(origins_subset, add=TRUE, col=adjustcolor("white", alpha=.8), xaxt="n", border="white", lwd=4) #still need to reproject!!!
LW <- 4
lines(x = c(-100 , -130), y = c(20 , 90), lty=2, col=adjustcolor("white", alpha=1), lwd=LW) #Mesoamerica
lines(x = c(-80 , -70), y = c(0 , 90), lty=2, col=adjustcolor("white", alpha=1), lwd=LW) #NW_Lowland_SA
lines(x = c(-74 , -5 ), y = c(5 , 90), lty=2, col=adjustcolor("white", alpha=1), lwd=LW) #N_Lowland_SA
lines(x = c(40 , 30), y = c(36 , 90), lty=2, col=adjustcolor("white", alpha=1), lwd=LW) #Fertile_Cresc
lines(x = c(110 , 70), y = c(40 , 90), lty=2, col=adjustcolor("white", alpha=1), lwd=LW) #Chinese_loess
lines(x = c(142 , 160), y = c(-5 , 90), lty=2, col=adjustcolor("white", alpha=1), lwd=LW) #New_Guinea
lines(x = c(-85 , -130), y = c(33 , -90), lty=2, col=adjustcolor("white", alpha=1), lwd=LW) #E_North_Ameri
lines(x = c(-68 , -75), y = c(-25 , -90), lty=2, col=adjustcolor("white", alpha=1), lwd=LW) #C/S_Andes
lines(x = c(-10 , -20), y = c( 15, -90), lty=2, col=adjustcolor("white", alpha=1), lwd=LW) #W_African_Sav
lines(x = c(25 , 40), y = c(9 , -90), lty=2, col=adjustcolor("white", alpha=1), lwd=LW) #Sudanic_Savan
lines(x = c(87 , 100), y = c(20 , -90), lty=2, col=adjustcolor("white", alpha=1), lwd=LW) #Ganges_E_Indi
lines(x = c(120 , 160), y = c(30 , -90), lty=2, col=adjustcolor("white", alpha=1), lwd=LW) #Lower-MiddleY
dev.off()
null device 
          1 

Import raster data

#subset and reorder origins. This is currently done at the end of the plot but should be moved forward.
# Load data for population density
load("PopD_all_December.rdata")
PopD.ALL
class       : RasterStack 
dimensions  : 288, 720, 207360, 18  (nrow, ncol, ncell, nlayers)
resolution  : 0.5, 0.5  (x, y)
extent      : -180, 180, -60, 84  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0 
names       :        fourK,        fiveK,         sixK,       sevenK,       eightK,        nineK,         tenK,      elevenK,      twelveK,    thirteenK,    fourteenK,     fifteenK,     sixteenK,   seventeenK,    eighteenK, ... 
min values  : 5.611358e-07, 1.067142e-06, 2.508241e-06, 6.317553e-06, 2.286934e-05, 7.631922e-05, 1.272693e-04, 2.118215e-04, 2.602175e-04, 3.226203e-04, 4.390267e-04, 5.572032e-04, 7.313966e-04, 8.286005e-04, 8.297062e-04, ... 
max values  :     2.051069,     2.013452,     2.142908,     1.888403,     1.863014,     1.880628,     1.650615,     1.678033,     1.697732,     1.499115,     1.517264,     1.443677,     1.464867,     1.453581,     1.436394, ... 
# Extract data to a matrix
Pop <- values(PopD.ALL)
r <- raster(PopD.ALL, 1)
r
class       : RasterLayer 
dimensions  : 288, 720, 207360  (nrow, ncol, ncell)
resolution  : 0.5, 0.5  (x, y)
extent      : -180, 180, -60, 84  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0 
data source : in memory
names       : fourK 
values      : 5.611358e-07, 2.051069  (min, max)

GAM smoothing models

Justification for General Adative Models.

We need to justify our decision to use a GAM over other models. This should include citations to back up those arguments.

Fit and plot GAM model with different degrees of freedom

We should make our decisions very transparent here. We should be able to justify our decision of 3 degrees of freedom over other possible values.

Density projections

# Read the polygons
library(rgdal)
rgdal: version: 1.2-5, (SVN revision 648)
 Geospatial Data Abstraction Library extensions to R successfully loaded
 Loaded GDAL runtime: GDAL 2.1.2, released 2016/10/24
 Path to GDAL shared files: 
 Loaded PROJ.4 runtime: Rel. 4.9.1, 04 March 2015, [PJ_VERSION: 491]
 Path to PROJ.4 shared files: (autodetected)
WARNING: no proj_defs.dat in PROJ.4 shared files
 Linking to sp version: 1.2-3 
getwd()
[1] "/Users/Ty/Desktop/Botero postdoc 2016/Human density and the origins of agriculture"
origins <- readShapePoly('Origins_updated.shp')
proj4string(origins) 
[1] NA
# Extract data
library(raster)
e <- extent(-180, 180, -60, 84)
all_cells <- extract(r, e, cellnumber = TRUE)
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
per.origin <- extract(r, origins, cellnumber = TRUE, buffer = 100000)
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
length(all_cells)
[1] 414720
for(i in 1:20){
all_cells <- all_cells[-which(per.origin[[i]][,1] %in% all_cells[,1]), ]
}
length(all_cells)
[1] 408656
names(per.origin) <- origins@data[, 1]
str(all_cells)
 num [1:204328, 1:2] 3033 3034 3035 3036 3037 ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:2] "cell" "value"
str(per.origin)
List of 20
 $ W_African_Sav: num [1:309, 1:2] 92506 92507 92508 92509 92510 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "cell" "value"
 $ Sudanic_Savan: num [1:306, 1:2] 99050 99051 99052 99053 99054 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "cell" "value"
 $ West Africa T: num [1:427, 1:2] 102609 102610 102611 103326 103327 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "cell" "value"
 $ Ethipian plat: num [1:275, 1:2] 106281 106282 106283 106998 106999 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "cell" "value"
 $ Fertile_Cresc: num [1:195, 1:2] 67404 67405 67406 68119 68120 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "cell" "value"
 $ E_North_Ameri: num [1:170, 1:2] 64270 64271 64984 64985 64986 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "cell" "value"
 $ New_Guinea   : num [1:24, 1:2] 127360 127361 127362 128080 128081 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "cell" "value"
 $ Mesoamerica  : num [1:73, 1:2] 93032 93033 93034 93035 93036 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "cell" "value"
 $ N_Lowland_SA : num [1:39, 1:2] 110373 110374 110375 111092 111093 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "cell" "value"
 $ NW_Lowland_SA: num [1:24, 1:2] 123319 123320 123321 123322 123323 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "cell" "value"
 $ Sava_W_India : num [1:34, 1:2] 83312 84031 84032 84749 84750 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "cell" "value"
 $ S_India      : num [1:18, 1:2] 99153 99154 99872 99873 99874 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "cell" "value"
 $ Ganges_E_Indi: num [1:92, 1:2] 85494 85495 85496 85497 85498 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "cell" "value"
 $ Lower-MiddleY: num [1:84, 1:2] 72598 72599 73318 73319 73320 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "cell" "value"
 $ Japanese     : num [1:36, 1:2] 59681 59682 60401 61121 61843 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "cell" "value"
 $ W_Yuman_E_Tib: num [1:131, 1:2] 72547 72548 72549 73267 73268 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "cell" "value"
 $ South trop ch: num [1:178, 1:2] 84818 84819 84820 84821 84822 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "cell" "value"
 $ Chinese_loess: num [1:258, 1:2] 62493 62494 62495 62496 62497 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "cell" "value"
 $ Southwes amaz: num [1:194, 1:2] 137758 137759 137760 137761 137762 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "cell" "value"
 $ C/S_Andes    : num [1:165, 1:2] 137736 137737 137738 137739 137740 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "cell" "value"
origin_vectors <- rep(NA, 3)

for(h in 1:20){
originI <- Pop[per.origin[[h]][, 1], ]
cell_vector <-  as.vector(per.origin[[h]][, 1])
x_values <- matrix(c(4:21), dim(originI)[1], 18, byrow=TRUE)
x_value_vector <- as.vector(x_values)
y_value_vector <- as.vector(originI)

all_vectors_pre <- cbind(rep(names(per.origin)[h], length(x_value_vector)),x_value_vector, y_value_vector, cell_vector)
origin_vectors <- rbind(origin_vectors, all_vectors_pre)
}

#names(origin_vectors)[1] <- "location"
origin_vectors <- origin_vectors[-1,]
origin_vectors
levels(all_vectors[,1])
 [1] "C/S_Andes"     "Chinese_loess" "E_North_Ameri" "Ethipian plat" "Fertile_Cresc"
 [6] "Ganges_E_Indi" "Japanese"      "Lower-MiddleY" "Mesoamerica"   "N_Lowland_SA" 
[11] "New_Guinea"    "not_origin"    "NW_Lowland_SA" "S_India"       "Sava_W_India" 
[16] "South trop ch" "Southwes amaz" "Sudanic_Savan" "W_African_Sav" "W_Yuman_E_Tib"
[21] "West Africa T"
all_vectors <- cbind(all_vectors, scale(as.numeric(all_vectors[,3])))
colnames(all_vectors) <- c("location_name", "x_values", "density_values", "cell_ID", "scaled_density_values")
all_vectors <- all_vectors[, c(1,2,3,5,4)]
all_vectors



par(mfrow=c(4,6), mar=c(0,0,0,0), xaxt="n")
for(h in 1:20){
#h <- 3
density_trend <- origin_vectors[which(origin_vectors[,1] == names(per.origin)[h]),]

plot(as.numeric(density_trend[,2]), as.numeric(density_trend[,4]), col=adjustcolor("cornflowerblue", alpha=0.8),  xlab="year", ylab="Density", ylim=c(-5,5), xlim=c(4,21), type="n")

points(as.numeric(density_trend[,2]), as.numeric(density_trend[,4]), cex=0.5, col=adjustcolor("cornflowerblue", 0.5))
mtext(as.character(density_trend[1,1]), 3, line=-1, cex=0.5)
}

#all origins
plot(as.numeric(density_trend[,2]), as.numeric(density_trend[,4]), col=adjustcolor("cornflowerblue", alpha=0.8),  xlab="year", ylab="Density", ylim=c(-5,5), xlim=c(4,21), type="n")

points(as.numeric(origin_vectors[,2]), as.numeric(origin_vectors[,4]), cex=0.5, col=adjustcolor("cornflowerblue", 0.5))
mtext("all origins", 3, line=-1, cex=0.5)

#not origins
not_origins <- subset(all_vectors, location_name == "not_origin")
plot(as.numeric(not_origins[,2]), as.numeric(not_origins[,4]), col=adjustcolor("cornflowerblue", alpha=0.8),  xlab="year", ylab="Density", ylim=c(-5,5), xlim=c(4,21), type="n")

points(as.numeric(not_origins[,2]), as.numeric(not_origins[,4]), cex=0.5, col=adjustcolor("cornflowerblue", 0.5))
mtext("all origins", 3, line=-1, cex=0.5)
par(mfrow=c(4,6), mar=c(0,0,0,0), xaxt="n")
for(h in 1:20){
#h <- 3
density_trend <- all_vectors[which(all_vectors[,1] == names(per.origin)[h]),]
plot(as.numeric(density_trend[,2]), as.numeric(density_trend[,4]), col=adjustcolor("cornflowerblue", alpha=0.8),  xlab="year", ylab="Density", ylim=c(-2,2), xlim=c(4,21), type="n")
for(g in levels(as.factor(density_trend[,5]))){
subbed <- subset(density_trend, cell_ID == g)
ordered_subbed <- subbed[order(subbed$x_values), ]
lines(as.numeric(ordered_subbed[,2]), as.numeric(ordered_subbed[,4]), lwd=.3, col=adjustcolor("cornflowerblue", 0.8))
}
mtext(as.character(density_trend[1,1]), 3, line=-1, cex=0.5)
}
#all origins
plot(as.numeric(density_trend[,2]), as.numeric(density_trend[,4]), col=adjustcolor("cornflowerblue", alpha=0.8),  xlab="year", ylab="Density", ylim=c(-2,2), xlim=c(4,21), type="n")
for(g in levels(as.factor(density_trend[,5]))){
subbed <- subset(density_trend, cell_ID == g)
ordered_subbed <- subbed[order(subbed$x_values), ]
lines(as.numeric(ordered_subbed[,2]), as.numeric(ordered_subbed[,4]), lwd=.3, col=adjustcolor("cornflowerblue", 0.8))
}
mtext("all origins", 3, line=-1, cex=0.5)

par(mfrow=c(4,6), mar=c(0,0,0,0))
for(h in 1:20){
#h <- 3
density_trend <- all_vectors[which(all_vectors[,1] == names(per.origin)[h]),]
plot(as.numeric(density_trend[,2]), as.numeric(density_trend[,4]), col=adjustcolor("cornflowerblue", alpha=0.8),  xlab="year", ylab="Density", ylim=c(-3,3), xlim=c(4,21), type="n", xaxt="n", yaxt="n")
points(as.numeric(density_trend[,2]), as.numeric(density_trend[,4]), cex=0.5, col=adjustcolor("grey", 0.5))
ordered_density_trend <- density_trend[order(density_trend$x_values), ]
gammer <- loess(as.numeric(ordered_density_trend[,4]) ~ as.numeric(ordered_density_trend[,2]))
summary(gammer)
lines(as.numeric(ordered_density_trend[,2]) ,predict(gammer),  col="cornflowerblue", lwd=2)
mtext(as.character(ordered_density_trend[1,1]), 3, line=-1, cex=0.5)
}
density_trend <- all_vectors[-1,]
plot(as.numeric(density_trend[,2]), as.numeric(density_trend[,4]), col=adjustcolor("cornflowerblue", alpha=0.8),  xlab="year", ylab="Density", ylim=c(-3,3), xlim=c(4,21), type="n", xaxt="n", yaxt="n")
points(as.numeric(density_trend[,2]), as.numeric(density_trend[,4]), cex=0.5, col=adjustcolor("grey", 0.5))
ordered_density_trend <- density_trend[order(density_trend$x_values), ]
gammer <- loess(as.numeric(ordered_density_trend[,4]) ~ as.numeric(ordered_density_trend[,2]))
summary(gammer)
Call:
loess(formula = as.numeric(ordered_density_trend[, 4]) ~ as.numeric(ordered_density_trend[, 
    2]))

Number of Observations: 54575 
Equivalent Number of Parameters: 4.29 
Residual Standard Error: 0.9855 
Trace of smoother matrix: 4.66  (exact)

Control settings:
  span     :  0.75 
  degree   :  2 
  family   :  gaussian
  surface  :  interpolate     cell = 0.2
  normalize:  TRUE
 parametric:  FALSE
drop.square:  FALSE 
length(ordered_density_trend[,2])
[1] 54575
length(predict(gammer))
[1] 54575
lines(as.numeric(ordered_density_trend[,2]) ,predict(gammer),  col="cornflowerblue", lwd=2)
mtext("all origins", 3, line=-1, cex=0.5)

span
the parameter α which controls the degree of smoothing.

The size of the neighbourhood is controlled by α (set by span or enp.target). For α < 1, the neighbourhood includes proportion α of the points, and these have tricubic weighting (proportional to (1 - (dist/maxdist)3)3). For α > 1, all points are used, with the ‘maximum distance’ assumed to be α^(1/p) times the actual maximum distance for p explanatory variables.

par(mfrow=c(4,6), mar=c(0,0,0,0))
for(h in 1:20){
#h <- 3
density_trend <- all_vectors[which(all_vectors[,1] == names(per.origin)[h]),]
ordered_density_trend <- density_trend[order(density_trend$x_values), ]
gammer <- loess(as.numeric(ordered_density_trend[,4]) ~ as.numeric(ordered_density_trend[,2]), span = .5)
summary(gammer)
predict_gam <- predict(gammer, se=TRUE)
plot(as.numeric(density_trend[,2]), as.numeric(density_trend[,4]), col=adjustcolor("cornflowerblue", alpha=0.8),  xlab="year", ylab="Density", ylim=c(-2,2), xlim=c(0,21), type="n", xaxt="n", yaxt="n")
#axis(1, label= seq(4,21, by=1), at=rev(seq(1,18, by=1)))
polygon(x=22-c(Start_of_early_window, Start_of_early_window, End_of_early_window_start_of_late_window, End_of_early_window_start_of_late_window), y=c(-2, 2, 2, -2), col=adjustcolor("limegreen", alpha= 0.2), border=adjustcolor("limegreen", alpha= 0.9))
polygon(x=22-c( End_of_early_window_start_of_late_window, End_of_early_window_start_of_late_window, End_of_late_window, End_of_late_window), y=c(-2, 2, 2, -2), col=adjustcolor("firebrick", alpha= 0.2), border=adjustcolor("firebrick", alpha= 0.9))
abline(h=0, lty=2, col="grey")
lines(ordered_density_trend[,2] ,predict_gam$fit,  col="cornflowerblue")
lines(ordered_density_trend[,2] ,  predict_gam$fit + predict_gam$se.fit,  col="grey", lty=1)
lines(ordered_density_trend[,2] ,  predict_gam$fit - predict_gam$se.fit,  col="grey", lty=1)
mtext(as.character(ordered_density_trend[1,1]), 3, line=-1, cex=0.5)
}

par(mfrow=c(2,5), mar=c(0,0,0,0))
for(j in seq(0.2, 2, by=.2)){
plot(as.numeric(density_trend[,2]), as.numeric(density_trend[,4]), col=adjustcolor("cornflowerblue", alpha=0.8),  xlab="year", ylab="Density", ylim=c(-3,3), xlim=c(0,21), type="n", xaxt="n")
axis(1, label= seq(4,21, by=1), at=rev(seq(1,18, by=1)))
polygon(x=22-c(Start_of_early_window, Start_of_early_window, End_of_early_window_start_of_late_window, End_of_early_window_start_of_late_window), y=c(-2, 2, 2, -2), col=adjustcolor("limegreen", alpha= 0.2), border=adjustcolor("limegreen", alpha= 0.9))
polygon(x=22-c( End_of_early_window_start_of_late_window, End_of_early_window_start_of_late_window, End_of_late_window, End_of_late_window), y=c(-2, 2, 2, -2), col=adjustcolor("firebrick", alpha= 0.2), border=adjustcolor("firebrick", alpha= 0.9))
for(h in 1:18){
#h <- 3
density_trend <- all_vectors[which(all_vectors[,1] == levels(all_vectors[,1])[h]),]
ordered_density_trend <- density_trend[order(density_trend$x_values), ]
gammer <- loess(as.numeric(ordered_density_trend[,4]) ~ as.numeric(ordered_density_trend[,2]), span = j)
summary(gammer)
predict_gam <- predict(gammer, se=TRUE)
abline(h=0, lty=2, col="grey")
lines(ordered_density_trend[,2] ,predict_gam$fit,  col="cornflowerblue")
}
mtext(paste("span = ", j), 3, line=-3, cex=0.5)
}

# need to add a global mean, an everything but the origins mean, and a buffer around the origins mean. 
# Function standardization
std <- function(x) {
  b <- (x - min(x)) / (max(x) - min(x))
  return(rev(b))
}
diff_df <- function(h){ 
# Calculating mean and 
global.means <- global.SD <- list()
for (j in 1:length(per.origin)) {
  #print(j)
  originI <- Pop[per.origin[[j]][, 1], ]
  time <- 21:4
  originI <- na.exclude(originI)
  b <- apply(originI, 1, std)
  nJ <- nrow(originI)
  predictions <- matrix(nrow = nJ, ncol = length(time))
  colnames(predictions) <- as.character(time)
  for(i in 1:nJ) {
    
    # Need to show a gradient of these df values. 
    model <- gam(b[, i] ~ s(time, df = h))
    col <- sample(rainbow(100), 1)
    predictions[i, ] <- predict(model)
    #plot(b[, i] ~ time)
    #lines(predictions[i, ] ~ time)
  }
  global.means[[j]] <- apply(predictions, 2, mean) 
  global.SD[[j]] <- apply(predictions, 2, sd)
}
names(global.means) <- paste(names(per.origin), "Means")
names(global.SD) <- paste(names(per.origin), "SD")
return(list(global.means, global.SD))
}
# Confirm that the x-axis is oriented correctly
for_3 <- diff_df(1)
global.means <- for_3[[1]]
global.SD <- for_3[[2]]
i <- 1
plot(4:21, global.means[[i]], col=adjustcolor("cornflowerblue", alpha=0.8),  xlab="year", ylab="Density", xaxt="n", type="n", ylim=c(0,1), xlim=c(0,20))
polygon(x=22-c(Start_of_early_window, Start_of_early_window, End_of_early_window_start_of_late_window, End_of_early_window_start_of_late_window) , y=c(-1, 2, 2, -1), col=adjustcolor("limegreen", alpha= 0.2), border=adjustcolor("limegreen", alpha= 0.9))
polygon(x= 22-c( End_of_early_window_start_of_late_window, End_of_early_window_start_of_late_window, End_of_late_window, End_of_late_window) , y=c(-1, 2, 2, -1), col=adjustcolor("firebrick", alpha= 0.2), border=adjustcolor("firebrick", alpha= 0.9))
originI <- Pop[per.origin[[i]][, 1], ]
for(j in 1:18){
points(23- c(jitter(rep(4, length(originI[,j])), 4.5)  + j), originI[,j], pch=19, cex=.1)
}
polygon(c(4:21,21:4) -3 , c(global.means[[i]] + abs(global.SD[[i]]), rev(global.means[[i]] - abs(global.SD[[i]]))), col="cornflowerblue")
lines(global.means[[i]], type="b", pch=names(global.means[[i]]))
axis(1, at=seq(1,18, by=1), label=rev(seq(4, 21, by=1)))
mtext(names(global.means)[1], 3, line=-2)

means_matrix <- matrix(rep(NA,19*20), 20, 19)
colnames(means_matrix) <- c("origin", rev(seq(4, 21, by=1)))
means_matrix[,1] <- names(global.means)
for(i in 1:20){
means_matrix[i,2:19] <- global.means[[i]]
}
kable(means_matrix, caption= "Mean values")
origin 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4
W_African_Sav Means 0.104899219543143 0.134188924520376 0.163478630086879 0.192768337143779 0.222058046838224 0.251347760590919 0.280637479498969 0.309927203966839 0.339216933658289 0.368506667593769 0.397796404279774 0.427086141832574 0.456375878173599 0.485665611342867 0.514955340645979 0.544245066868078 0.57353479164412 0.602824516011452
Sudanic_Savan Means -0.10724896174395 -0.0533187951601074 0.000611371835778832 0.0545415398043657 0.108471709349614 0.162401880969061 0.216332054920623 0.27026223113924 0.324192409243395 0.378122588550681 0.432052768094689 0.485982946660064 0.539913122918328 0.593843295639399 0.647773464669011 0.701703631010656 0.755633796252142 0.80956396123006
West Africa T Means -0.143267389894562 -0.081797707917561 -0.0203280253965994 0.041141658440579 0.102611344483474 0.164081033548429 0.225550726263179 0.287020422967273 0.348490123689458 0.409959828135003 0.471429535677672 0.532899245364544 0.594368956014526 0.655838666396217 0.71730837598331 0.778778084964094 0.840247793906883 0.901717502970059
Ethipian plat Means -0.0387859681196021 0.0168899777868711 0.072565924122332 0.128241871472059 0.183917820466275 0.239593771621315 0.295269725203985 0.350945681114808 0.406621638871376 0.462297597658917 0.517973556445799 0.573649514099709 0.62932546960438 0.685001422192243 0.740677371916286 0.796353319602989 0.852029266497986 0.90770521330897
Fertile_Cresc Means 0.465203780475435 0.468037218114714 0.470870656450899 0.473704096660508 0.476537540459374 0.479370990131535 0.482204448254042 0.485037917303028 0.487871399203528 0.490704895015582 0.493538404739892 0.49637192722466 0.49920546009688 0.502039000068305 0.504872544201404 0.507706090341499 0.510539637088669 0.513373183917568
E_North_Ameri Means -0.103309179197518 -0.0439832369861447 0.0153427055932419 0.0746686490173886 0.133994593753526 0.193320540074041 0.252646487951773 0.311972437000452 0.371298386536891 0.430624335703652 0.489950283626113 0.549276229602186 0.608602173484197 0.667928115720655 0.727254057042701 0.786579998255987 0.845905939984436 0.90523188202598
New_Guinea Means 0.0780223010615444 0.109513421952105 0.141004543543209 0.172495666943759 0.203986793655765 0.235477925494105 0.266969064415624 0.298460212309609 0.329951370761434 0.361442540814153 0.392933722788478 0.424424916132718 0.45591611919871 0.487407329372465 0.518898544184308 0.550389761512579 0.58188097970604 0.613372198119623
Mesoamerica Means -0.103254774123441 -0.0421007982787409 0.019053177959811 0.0802071551140336 0.141361133709426 0.202515114080774 0.26366909630437 0.324823080173061 0.385977065267956 0.447131051030508 0.508285036833424 0.569439022046871 0.630593006197502 0.691746989012972 0.752900970745524 0.814054952048963 0.875208933624754 0.936362915408461
N_Lowland_SA Means 0.000405826277542806 0.0397696676253803 0.0791335096495173 0.118497353395241 0.157861200250496 0.197225051836574 0.236588909886753 0.27595277609575 0.315316651926943 0.354680538413954 0.39404443596328 0.433408344162805 0.472772261526379 0.512136185602532 0.551500114110901 0.59086404511585 0.630227977094757 0.669591909407498
NW_Lowland_SA Means 0.150545407239587 0.172180091043831 0.193814775374647 0.215449461081994 0.237084149345124 0.258718841612232 0.280353539499686 0.30198824465636 0.323622958626372 0.345257682660072 0.366892417504026 0.388527163206443 0.410161918861245 0.431796682592268 0.453431452121843 0.475066225079913 0.496700999360675 0.518335774005676
Sava_W_India Means -0.142117662153824 -0.0820276080009521 -0.0219375533374597 0.0381525025547106 0.0982425605037868 0.158332621254832 0.218422685383102 0.278512753236216 0.338602824930473 0.398692900332745 0.458782979070348 0.518873060551069 0.578963143964694 0.639053228343797 0.699143313059593 0.759233398122439 0.819323483848039 0.879413569953719
S_India Means -0.152229061714256 -0.0878275875926912 -0.0234261129206527 0.0409753630905714 0.105376841360717 0.16977832272666 0.234179807831007 0.298581297034492 0.362982790419324 0.427384287834698 0.491785788886 0.55618729293457 0.620588799091033 0.684990306325772 0.749391814044776 0.813793322117339 0.878194830622834 0.942596339332975
Ganges_E_Indi Means -0.170251227235162 -0.107488045725873 -0.0447248636051514 0.0180383200108272 0.0808015061810664 0.143564695945494 0.2063278902045 0.269091089618451 0.331854294549827 0.394617505018045 0.457380720681986 0.520143940814235 0.582907164368936 0.645670390051003 0.708433616866833 0.771196844382705 0.833960072531624 0.896723301009
Lower-MiddleY Means -0.222419314851421 -0.153472073454121 -0.0845248312696055 -0.0155775871312725 0.0533696604127891 0.122316912897304 0.191264171744624 0.260211438138581 0.329158712896134 0.398105996326573 0.467053288195014 0.536000587697266 0.604947893430301 0.67389520345079 0.742842516027211 0.811789829912948 0.880737144338505 0.949684458889426
Japanese Means 0.207909573852624 0.238694374328487 0.269479175586574 0.300263978892804 0.331048786008847 0.361833599118817 0.392618420617698 0.423403252841472 0.454188097768294 0.484972956701335 0.5157578299626 0.54654271665773 0.577327614448995 0.608112519834166 0.638897429758609 0.669682341987937 0.700467255026035 0.731252168229076
W_Yuman_E_Tib Means -0.190865103156459 -0.128188388051326 -0.0655116722581322 -0.0028349547568992 0.059841765714233 0.122518490471088 0.185195220746088 0.247871957563144 0.310548701660478 0.373225453403681 0.435902212702472 0.49857897895264 0.561255750982275 0.623932527118473 0.68660930593375 0.749286086425131 0.811962867980633 0.874639649973257
South trop ch Means -0.226691723507628 -0.155639930699377 -0.0845881370655499 -0.0135363413793945 0.057515457890293 0.128567262368368 0.199619073553247 0.270670892604341 0.341722720204182 0.412774556483464 0.483826400918589 0.554878252400401 0.625930109268281 0.696981969457782 0.768033831329109 0.839085693907099 0.910137556735518 0.981189419611597
Chinese_loess Means -0.180557406298825 -0.114768295671173 -0.0489791842578611 0.0168099291166325 0.0825990459384166 0.148388167813397 0.214177296244994 0.279966432413418 0.345755577007275 0.411544730255149 0.477333891879118 0.54312306095813 0.608912235849198 0.674701414453165 0.740490595041184 0.806279776550925 0.872068958421914 0.937858140371587
Southwes amaz Means -0.0237969365966393 0.021469417190652 0.0667357717383504 0.112002128224275 0.157268488203304 0.202534853472623 0.247801225954001 0.293067607531449 0.338333999848707 0.38360040409157 0.428866820779647 0.474133249586047 0.519399689119871 0.56466613699365 0.609932590875371 0.655199048591716 0.700465508189352 0.745731968433817
C/S_Andes Means -0.178396371705524 -0.118024294268812 -0.0576522160895443 0.00271986394360668 0.0630919472397263 0.123464035329554 0.183836129731935 0.244208231814901 0.304580342689608 0.364952463075518 0.425324593159607 0.485696732455348 0.546068879658203 0.60644103273334 0.666813189862491 0.727185349512935 0.787557510401936 0.847929671711528
#global.SD
SD_matrix <- matrix(rep(NA,19*20), 20, 19)
colnames(SD_matrix) <- c("origin", rev(seq(4, 21, by=1)))
SD_matrix[,1] <- names(global.SD)
for(i in 1:20){
SD_matrix[i,2:19] <- global.SD[[i]]
}
kable(SD_matrix, caption= "SD values")
origin 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4
W_African_Sav SD 0.141389728189349 0.127206280461234 0.113071328803115 0.0990056467818181 0.085043611801913 0.0712461848916759 0.0577315071568506 0.0447564519092976 0.0329644953028415 0.0241553448939908 0.0222172925051982 0.0285839125579161 0.039417972259343 0.0519982451823134 0.0653235252939881 0.0790178012453641 0.0929180680855395 0.106944033642494
Sudanic_Savan SD 0.0445678405436582 0.0386831084720568 0.0328819720981679 0.0272179357411408 0.0217981350497281 0.0168597776197881 0.0129651953993825 0.0112557240838648 0.0126505844624047 0.0163748064400989 0.0212363470748164 0.0266192008736411 0.0322634877517376 0.0380530534393487 0.0439304974660208 0.0498647555884257 0.0558377164983909 0.061838166069546
West Africa T SD 0.0287862136277306 0.026879465665257 0.0251778886370751 0.0237256674317954 0.0225709841481388 0.0217612536887934 0.0213357869026501 0.0213176042210816 0.0217077293126121 0.0224849195050478 0.0236109837125017 0.0250388973393629 0.0267203129081378 0.0286105716658546 0.0306710852751722 0.0328698511343342 0.0351809569369125 0.0375836842106332
Ethipian plat SD 0.122132406046021 0.111086534908233 0.100306106039733 0.0898866765453403 0.0799694776193378 0.0707659737191665 0.0625917849585397 0.0559002920936676 0.0512752969106703 0.0493018401585638 0.0502930253783019 0.0540861038098046 0.0601533530722638 0.067887746235314 0.0767871553986695 0.0864927128962345 0.0967621446268642 0.107433872812645
Fertile_Cresc SD 0.332823431663763 0.304490066226683 0.276196898802325 0.247957690134294 0.219793239314287 0.191736493336918 0.163842792659721 0.136212340113258 0.109045428534709 0.0827995901029643 0.0587230882568977 0.0408508487924327 0.0389479619606044 0.054707002803952 0.0780802701610951 0.104057487628886 0.131099780727889 0.158663492744478
E_North_Ameri SD 0.0111478843415654 0.0105537580553609 0.0100801528632332 0.00974465712238077 0.00956181938789069 0.00954042047920891 0.00968153083923648 0.00997825823797907 0.0104173132437485 0.0109816378984685 0.011653046942279 0.0124141777758803 0.0132495769375559 0.0141460926746219 0.0150928379001862 0.0160809435309792 0.017103242650645 0.0181539596691189
New_Guinea SD 0.0862348900319317 0.0802994408474221 0.074426043970021 0.0686306325244304 0.0629347543396364 0.057368064130348 0.0519720903347448 0.0468059130873167 0.0419545084281555 0.0375401120968095 0.0337347182737104 0.0307651486069222 0.0288903003016857 0.0283283681471193 0.0291553652909964 0.0312612555259039 0.0344120437989608 0.0383510535617854
Mesoamerica SD 0.0460480691898844 0.0438275821937302 0.0417295078694515 0.0397732228528433 0.0379806427534924 0.0363759769906451 0.034985091994081 0.0338343624106085 0.0329489596491325 0.0323506761628198 0.0320555925393017 0.0320720792204106 0.0323996612158642 0.0330290842393224 0.0339435617472528 0.0351208345293728 0.0365355078910419 0.0381611891449885
N_Lowland_SA SD 0.126361668783694 0.113753925843932 0.101254440047423 0.0889088818933135 0.0767915268619725 0.0650300669434964 0.0538581687912675 0.0437300453098829 0.035549306666144 0.0309032588451008 0.0314020937817763 0.0368373922441298 0.045472159695575 0.0558414091145397 0.0671463358827674 0.0789861990890934 0.091152787456489 0.103530978322292
NW_Lowland_SA SD 0.131218479811056 0.120555221191725 0.109977213275324 0.0995116460460398 0.0891981061747257 0.0790960858312105 0.0692981504251234 0.0599535712479233 0.0513106411694127 0.0437868374489756 0.0380518895037199 0.034996560561556 0.0353231635684655 0.0389467085476935 0.0450790402586245 0.0528540175032157 0.0616532886641193 0.0710975554590369
Sava_W_India SD 0.0143048310349855 0.0145094191559861 0.0151541306452222 0.0161864598597809 0.0175380917470914 0.0191415048515154 0.0209389377132182 0.0228847190483282 0.0249441567519155 0.0270913430640052 0.0293069972821532 0.0315767098401866 0.0338896208658854 0.0362374596129815 0.0386138555253783 0.0410138450971826 0.0434335175259682 0.0458697581707579
S_India SD 0.0175373810111254 0.016431713233993 0.0154099222974909 0.0144897635580855 0.0136917430111427 0.0130383066160943 0.0125520549816957 0.0122529082135161 0.0121546890179408 0.0122622266334193 0.0125702415654925 0.0130645620190655 0.0137250729628772 0.0145291265277004 0.015454334431721 0.0164803044444823 0.0175894134114952 0.0187669268247465
Ganges_E_Indi SD 0.0247407484441615 0.0231154113250543 0.0228873831603976 0.0240963655202915 0.0265467475604452 0.0299352171442637 0.0339823053973127 0.0384807660563184 0.0432901147438565 0.0483176064010719 0.0535017801954633 0.0588012090086263 0.0641873518497996 0.0696400913290164 0.075144931410409 0.080691209789222 0.0862709349191979 0.0918780135670332
Lower-MiddleY SD 0.0111964646991441 0.0110007704190186 0.0110705714391159 0.0114009923936636 0.0119704709708317 0.0127470072213614 0.0136954254501327 0.0147826799818087 0.015980457955985 0.0172657724974585 0.0186205051534908 0.0200305757908087 0.0214850914439893 0.0229756124320653 0.0244955669411468 0.0260398014385208 0.027604241586932 0.029185638445653
Japanese SD 0.155274434484446 0.142748052663026 0.130253755375822 0.117801752006653 0.105407032599831 0.0930924811777263 0.0808947179051775 0.0688758195070342 0.0571487477993645 0.0459375430676068 0.0357311326225471 0.027664908318808 0.0240032844565609 0.0266297815246696 0.0341219852468084 0.0440641743846799 0.0551468042002294 0.0668046819245868
W_Yuman_E_Tib SD 0.0194825129805913 0.0180489878568931 0.0167705290570465 0.0156850998136583 0.0148351303999185 0.0142627786854846 0.0140021298365873 0.0140705168963491 0.0144632732808888 0.0151552013299024 0.0161077934500136 0.0172779896432119 0.0186248189451066 0.0201128286742716 0.0217130126734626 0.0234023719184359 0.0251629520850473 0.0269808146864361
South trop ch SD 0.0158809093678173 0.0157424075890833 0.0159889937031962 0.0166035191575685 0.0175473695625691 0.0187709324066404 0.0202235015162359 0.02185947154732 0.0236407981054066 0.0255370810949326 0.0275245708939676 0.0295848912702664 0.0317038461338131 0.0338704324952817 0.0360760697171865 0.0383140143879305 0.0405789217912716 0.0428665185204352
Chinese_loess SD 0.0461466462169304 0.0396066328499543 0.0332645662689112 0.027258961224203 0.0218687940567633 0.0176666610046332 0.0156413299836067 0.0166091833472904 0.0201432899623923 0.0251855629187174 0.0310088086115247 0.037248529196348 0.0437267955926144 0.0503516171832409 0.0570719810788334 0.0638577300705702 0.0706900374086199 0.0775565995878492
Southwes amaz SD 0.105884652563484 0.0968590200943272 0.0878843825723666 0.0789781262933419 0.0701662951910564 0.0614894979171078 0.0530140788139324 0.0448543371036371 0.0372184809270723 0.0305025208762825 0.0254455662672739 0.0231610539271356 0.0244392394366502 0.0288097690952561 0.0351370672906904 0.0425571207366903 0.0505913816003737 0.0589894194422519
C/S_Andes SD 0.0736266849425639 0.0656336428080509 0.0578570930401963 0.0503973528141999 0.0434180254254664 0.037190569998016 0.0321548419639858 0.0289397825966489 0.0281756977535175 0.0300501350637253 0.0341311148926048 0.0397446482453903 0.0463370560022636 0.0535480163438101 0.0611591279620439 0.0690381735300364 0.0771030576544312 0.0853010857853665
par(mfrow=c(4,5), mar=c(0,0,0,0))
for(j in 1:20){
plot(means_matrix[1,2:19], col=adjustcolor("cornflowerblue", alpha=0.8), pch=names(means_matrix[1,2:19]), type="n", xlab="year", ylab="Density", xaxt="n", ylim=c(0,1))
originI <- Pop[per.origin[[j]][, 1], ]
for(h in 1:18){
points(23- c(jitter(rep(4, length(originI[,h])), 4.5)  + h), originI[,h], pch=19, cex=.1)
}
  
lines(means_matrix[j,2:19], col=adjustcolor("cornflowerblue", alpha=0.8), pch=names(means_matrix[j,2:19]), type="b", xlab="year", ylab="Density", xaxt="n")
}
axis(1, at=seq(1,18, by=1), label=rev(seq(4, 21, by=1)))

par(mfrow=c(4,5), mar=c(0,0,0,0))
for_3 <- diff_df(1)
global.means <- for_3[[1]]
global.SD <- for_3[[2]]
for(i in 1:20){
  
plot(4:21, global.means[[i]], col=adjustcolor("cornflowerblue", alpha=0.8),  xlab="year", ylab="Density", xaxt="n", type="n", ylim=c(0,1), xlim=c(0,22), xaxt="n", yaxt="n")
polygon(x=22-c(Start_of_early_window, Start_of_early_window, End_of_early_window_start_of_late_window, End_of_early_window_start_of_late_window) , y=c(-1, 2, 2, -1), col=adjustcolor("limegreen", alpha= 0.2), border=adjustcolor("limegreen", alpha= 0.9))
polygon(x= 22-c( End_of_early_window_start_of_late_window, End_of_early_window_start_of_late_window, End_of_late_window, End_of_late_window) , y=c(-1, 2, 2, -1), col=adjustcolor("firebrick", alpha= 0.2), border=adjustcolor("firebrick", alpha= 0.9))  
  
polygon(c(4:21,21:4) -3 , c(global.means[[i]] + abs(global.SD[[i]]), rev(global.means[[i]] - abs(global.SD[[i]]))), col="cornflowerblue")
lines(global.means[[i]])
#axis(1, at=seq(1,18, by=1), label=rev(seq(4, 21, by=1)))
mtext(names(global.means)[i], 3, line=-1, cex=.5, adj=.3)
}

GAM model using one degree of freedom

par(mfrow=c(4,5), mar=c(0,0,0,0))
for_3 <- diff_df(2)
global.means <- for_3[[1]]
global.SD <- for_3[[2]]
for(i in 1:20){
plot(4:21, global.means[[i]], col=adjustcolor("cornflowerblue", alpha=0.8),  xlab="year", ylab="Density", xaxt="n", type="n", ylim=c(0,1), xlim=c(0,22), xaxt="n", yaxt="n")
polygon(x=22-c(Start_of_early_window, Start_of_early_window, End_of_early_window_start_of_late_window, End_of_early_window_start_of_late_window) , y=c(-1, 2, 2, -1), col=adjustcolor("limegreen", alpha= 0.2), border=adjustcolor("limegreen", alpha= 0.9))
polygon(x= 22-c( End_of_early_window_start_of_late_window, End_of_early_window_start_of_late_window, End_of_late_window, End_of_late_window) , y=c(-1, 2, 2, -1), col=adjustcolor("firebrick", alpha= 0.2), border=adjustcolor("firebrick", alpha= 0.9))
polygon(c(4:21,21:4) -3 , c(global.means[[i]] + abs(global.SD[[i]]), rev(global.means[[i]] - abs(global.SD[[i]]))), col="cornflowerblue")
lines(global.means[[i]])
#axis(1, at=seq(1,18, by=1), label=rev(seq(4, 21, by=1)))
mtext(names(global.means)[i], 3, line=-1, cex=.5, adj=.3)
}

GAM model using two degree of freedom

par(mfrow=c(4,5), mar=c(0,0,0,0))
for_3 <- diff_df(3)
global.means <- for_3[[1]]
global.SD <- for_3[[2]]
for(i in 1:20){
plot(4:21, global.means[[i]], col=adjustcolor("cornflowerblue", alpha=0.8),  xlab="year", ylab="Density", xaxt="n", type="n", ylim=c(0,1), xlim=c(0,22), xaxt="n", yaxt="n")
polygon(x=22-c(Start_of_early_window, Start_of_early_window, End_of_early_window_start_of_late_window, End_of_early_window_start_of_late_window) , y=c(-1, 2, 2, -1), col=adjustcolor("limegreen", alpha= 0.2), border=adjustcolor("limegreen", alpha= 0.9))
polygon(x= 22-c( End_of_early_window_start_of_late_window, End_of_early_window_start_of_late_window, End_of_late_window, End_of_late_window) , y=c(-1, 2, 2, -1), col=adjustcolor("firebrick", alpha= 0.2), border=adjustcolor("firebrick", alpha= 0.9))
polygon(c(4:21,21:4) -3 , c(global.means[[i]] + abs(global.SD[[i]]), rev(global.means[[i]] - abs(global.SD[[i]]))), col="cornflowerblue")
lines(global.means[[i]])
#axis(1, at=seq(1,18, by=1), label=rev(seq(4, 21, by=1)))
mtext(names(global.means)[i], 3, line=-1, cex=.5, adj=.3)
}

GAM model using three degree of freedom

par(mfrow=c(4,5), mar=c(0,0,0,0))
for_3 <- diff_df(17)
global.means <- for_3[[1]]
global.SD <- for_3[[2]]
for(i in 1:20){
plot(4:21, global.means[[i]], col=adjustcolor("cornflowerblue", alpha=0.8),  xlab="year", ylab="Density", xaxt="n", type="n", ylim=c(0,1), xlim=c(0,22), xaxt="n", yaxt="n")
polygon(x=22-c(Start_of_early_window, Start_of_early_window, End_of_early_window_start_of_late_window, End_of_early_window_start_of_late_window) , y=c(-1, 2, 2, -1), col=adjustcolor("limegreen", alpha= 0.2), border=adjustcolor("limegreen", alpha= 0.9))
polygon(x= 22-c( End_of_early_window_start_of_late_window, End_of_early_window_start_of_late_window, End_of_late_window, End_of_late_window) , y=c(-1, 2, 2, -1), col=adjustcolor("firebrick", alpha= 0.2), border=adjustcolor("firebrick", alpha= 0.9))   
  
polygon(c(4:21,21:4) -3 , c(global.means[[i]] + abs(global.SD[[i]]), rev(global.means[[i]] - abs(global.SD[[i]]))), col="cornflowerblue")
lines(global.means[[i]])
#axis(1, at=seq(1,18, by=1), label=rev(seq(4, 21, by=1)))
mtext(names(global.means)[i], 3, line=-1, cex=.5, adj=.3)
}

GAM model using 17 degree of freedom

Productivity

# Load patricks productivity PCA data
load('Productivity_ALL.RDATA')
# Load origin shapefiles
origins <- readShapePoly('Origins_updated.shp')
origin.time.region <- c(2, 2, 1, 1, 1, 2, 2, 1, 2, 2, 
                        2, 2, 1, 2, 2, 2, 2, 2, 2, 2) # 1 = early; 2 = middle
# Extract the data
prod.origin <- extract(Productivity.ALL, origins)
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
# Mean and SD per region
means <- lapply(prod.origin, colMeans, na.rm = TRUE)
sds <- lapply(prod.origin, sd, na.rm = TRUE)
names(means) <- origins@data$CONTINENT
ymax <- max(unlist(means))
ymin <- min(unlist(means))
time <- 4:21
# Plot
#pdf("productivity.pdf", 20, 30) 
par(mfrow = c(5, 4), mar = c(2, 2, 2, 0))
for (i in 1:length(means)) {
  plot(y = means[[i]], x = time, xlim = c(21, 4), ylim = c(ymin, ymax),
       main = names(means)[i], cex.main = 1, cex.lab = 1, cex.axis = 1,
       ylab = "Productivity (PCA axis)", xlab = "Thousand of years ago (k)",
       pch = 20, lwd = 1, type = "l", 
       col = c("purple", "green")[origin.time.region[i]])
  up <- sds[[i]] + means[[i]]
  down <-  means[[i]] - sds[[i]]
  lines(up ~ time, lty = 2)
  lines(down ~ time, lty = 2)
  
}

#dev.off()

Compare rates between origins and not-origins

Compare rates between different time periods

Setup final figure

Frame in the layout

a <- layout(matrix(c(
    1, 1, 1, 1, 1, 1, 1, 1,
    3,  6, 7, 8, 9, 10, 11, 4, 
    3,  5, 5, 5, 5, 5, 5,   4, 
    3,  12, 13, 14, 15, 16, 17, 4,
    2, 2, 2, 2, 2, 2, 2, 2
    ), 5, 8, byrow=TRUE), width=c(1, 1, 1, 1, 1, 1, 1, 1), height=c(0.5, 1, 1.5, 1, 0.5))
layout.show(a)

Make blank template plots

frameplot <- function(){
    plot(21:0,rep(0, 22), xlim=c(21,0), ylim=c(-3, 2.25), type="n", xaxt="n", yaxt="n", xlab="", ylab="")
}
frameplot_bottom <- function(){
    plot(21:0,rep(0, 22), xlim=c(21,0), ylim=c(-3.25, 2), type="n", xaxt="n", yaxt="n", xlab="", ylab="")
}
frameplot()

frameplot_bottom()

Trend through time panel

Setup the plot template for small panel plots (#6-17 on layout panel)

###################
type_number <- 8
complex_figure <- function(type_number, location_name, i, means, sds){
        
#polygon(x=c(-30,-30,30,30), y=c(-30,30,30,-30), col="black")  
  
abline(h=0, lty=2)          
if(i < 6)   polygon(x=c(12,12,8.2,8.2), y=c(-3,3,3,-3), col=adjustcolor("cornflowerblue", alpha=0.2), border=NA)                    
if(i > 5)   polygon(x=c(8.2,8.2,4.2,4.2), y=c(-3,3,3,-3), col=adjustcolor("cornflowerblue", alpha=0.2), border=NA)
            
  
    match <- domestication_times[ which(domestication_times$Region == levels(domestication_times$Region)[ type_number]), 9]
    maxer <- max(match, na.rm=TRUE)
    break_one_1 <- maxer
            break_two_1 <- maxer - quantile(j)[2]
                
#   polygon(x=c(break_two_1, break_two_1, break_one_1, break_one_1), y=c(0, 1, 1, 0), col=adjustcolor("cornflowerblue", alpha=0.5), border=NA)
        lines(x=c(break_one_1, break_one_1), y=c(-3,3), col=adjustcolor("cornflowerblue", alpha=0.7), lwd=3)    
  
  
  match <- domestication_times[ which(domestication_times$Region == levels(domestication_times$Region)[ type_number]), 10]
    maxer <- max(match, na.rm=TRUE)
    break_one_2 <- maxer
            break_two_2 <- maxer - quantile(j)[2]
                
#   polygon(x=c(break_two_2, break_two_2, break_one_2, break_one_2), y=c(1, 2, 2, 1), col=adjustcolor("limegreen", alpha=0.5), border=NA)
        lines(x=c(break_one_2, break_one_2), y=c(-3,3), col=adjustcolor("cornflowerblue", alpha=1), lwd=3)  
    
        
                        
    match <- domestication_times[ which(domestication_times$Region == levels(domestication_times$Region)[ type_number]), 9]
    maxer <- max(match, na.rm=TRUE)
    j <- ecdf(maxer-match)
    print(j)
    
x_seq <- rev(c(0,seq(0, maxer, length.out=100)))
y_seq <- c(0, j(seq(0, maxer, length.out=100))) 
#lines(x_seq, y_seq, type="l", ylim=c(-1,1))
polygon(c(0, x_seq), c(0, y_seq) -3, border=NA, col=adjustcolor("white", alpha=1), lwd=.5)
polygon(c(0, x_seq), c(0, y_seq) -3, border="cornflowerblue", col=adjustcolor("cornflowerblue", alpha=.5), lwd=.5)
#abline(v= maxer - quantile(j)[2])
    match <- domestication_times[ which(domestication_times$Region == levels(domestication_times$Region)[ type_number]), 10]
    maxer <- max(match, na.rm=TRUE)
    j <- ecdf(maxer-match)
    print(j)
    
x_seq <- rev(c(0,seq(0, maxer, length.out=100)))
y_seq <- c(0, j(seq(0, maxer, length.out=100))) 
#lines(x_seq, y_seq)
polygon(c(0, x_seq), c(0, y_seq) -3, border="white", col=adjustcolor("white", alpha=1), lwd=.5)
polygon(c(0, x_seq), c(0, y_seq) -3, border="white", col=adjustcolor("cornflowerblue", alpha=1), lwd=.5)
    
        
        
        
        #abline(v=11)
    type <- 3
        
        if(type == 1){
    x <- c(means[[i]] , means[[i]]  + abs(sds[[i]]), means[[i]]  - abs(sds[[i]]))
    scaled <- scale(x , center=TRUE)
    meanss <- scaled[1:18]
    sdss_plus <- scaled[19:36]
    sdss_minus <- scaled[37:54]
    #abline(v=10, col="red")
    length(scaled)
    #lines(4:21, means[[i]] + sds[[i]])
    #polygon(x=c(4:21, 21:4), y=c(sdss_plus, rev(sdss_minus)), col=adjustcolor("firebrick", alpha=1), border="white")
    polygon(x=c(21:4,4:21), y=c(sdss_plus, rev(sdss_minus)), col=adjustcolor("firebrick", alpha=1), border="white") 
    }
    
    if(type == 2){
#h <- 3
density_trend <- all_vectors[which(all_vectors[,1] == location_name ),]
#plot(as.numeric(density_trend[,2]), as.numeric(density_trend[,4]), col=adjustcolor("cornflowerblue", alpha=0.8),  xlab="year", ylab="Density", ylim=c(-2,2), xlim=c(4,21), type="n")
for(g in levels(as.factor(density_trend[,5]))){
subbed <- subset(density_trend, cell_ID == g)
ordered_subbed <- subbed[order(subbed$x_values), ]
lines(22-as.numeric(ordered_subbed[,2]), as.numeric(ordered_subbed[,4]), lwd=.3, col=adjustcolor("limegreen", 0.3))
}
density_trend <- all_vectors[which(all_vectors[,1] == location_name),]
ordered_density_trend <- density_trend[order(density_trend$x_values), ]
#gammer <- loess(as.numeric(ordered_density_trend[,4]) ~ as.numeric(ordered_density_trend[,2]), span = 1)
gammer <- gam(as.numeric(ordered_density_trend[,4]) ~ s(as.numeric(ordered_density_trend[,2]), df = 3))
summary(gammer)
predict_gam <- predict(gammer, se=TRUE)
abline(h=0, lty=2, col="grey")
#lines(rev(ordered_density_trend[,2]) ,  predict_gam$fit + predict_gam$se.fit,  col="orange", lty=1, lwd=1)
#lines(rev(ordered_density_trend[,2]) ,  predict_gam$fit - predict_gam$se.fit,  col="orange", lty=1, lwd=1)
polygon(x=3+c(rev(ordered_density_trend[,2]), ordered_density_trend[,2] ), y=c(predict_gam$fit, rev(predict_gam$fit)), col=adjustcolor("firebrick", alpha=.5),bty="n", lwd=.2)
lines(3+rev(as.numeric(ordered_density_trend[,2])) ,predict_gam$fit,  col="firebrick", lwd=1)
    }
if(type == 3){
    
#h <- 3
density_trend <- all_vectors[which(all_vectors[,1] == location_name ),]
#plot(as.numeric(density_trend[,2]), as.numeric(density_trend[,4]), col=adjustcolor("cornflowerblue", alpha=0.8),  xlab="year", ylab="Density", ylim=c(-2,2), xlim=c(4,21), type="n")
for(g in levels(as.factor(density_trend[,5]))){
subbed <- subset(density_trend, cell_ID == g)
ordered_subbed <- subbed[order(subbed$x_values), ]
lines(3+rev(as.numeric(ordered_subbed[,2])), as.numeric(ordered_subbed[,4]), lwd=.3, col=adjustcolor("limegreen", 0.3))
}
density_trend <- all_vectors[which(all_vectors[,1] == location_name),]
ordered_density_trend <- density_trend[order(density_trend$x_values), ]
gammer <- loess(as.numeric(ordered_density_trend[,4]) ~ as.numeric(ordered_density_trend[,2]), span = 1)
summary(gammer)
predict_gam <- predict(gammer, se=TRUE)
abline(h=0, lty=2, col="grey")
#lines(rev(ordered_density_trend[,2]) ,  predict_gam$fit + predict_gam$se.fit,  col="orange", lty=1, lwd=1)
#lines(rev(ordered_density_trend[,2]) ,  predict_gam$fit - predict_gam$se.fit,  col="orange", lty=1, lwd=1)
polygon(x=3+c(rev(ordered_density_trend[,2]), ordered_density_trend[,2] ), y=c(predict_gam$fit, rev(predict_gam$fit)), col=adjustcolor("firebrick", alpha=.5),bty="n", lwd=.2)
lines(3+rev(as.numeric(ordered_density_trend[,2])) ,predict_gam$fit,  col="firebrick", lwd=1)
    }
    
    
#means_long_y <- c(1,1,1,1,1, meanss)
#means_long_x <- c(0:4, 4:21)
 
        #   break_one <- break_one_2
        #   break_two <- break_two_2
        #       polygon(x=c(break_one, break_one, 22, 22), y=c(1, 2, 2, 1), col=adjustcolor("white", alpha=0.8), border=NA)
        #       polygon(x=c(break_two, break_two, break_one, break_one), y=c(1, 2, 2, 1), col=adjustcolor("white", alpha=0), border=NA)
            #   polygon(x=c(-1,-1, break_two , break_two), y=c(1.9, 3.1, 3.1, 1.9), col=adjustcolor("white", alpha=0.8), border=NA) 
                #abline(v= break_one, col="white")
                #abline(v= break_two, col="white")
                
            #   break_one <- break_one_1
        #   break_two <- break_two_1
        #       polygon(x=c(break_one, break_one, 22, 22), y=c(0, 1, 1, 0), col=adjustcolor("white", alpha=0.8), border=NA)
        #       polygon(x=c(break_two, break_two, break_one, break_one), y=c(0, 1, 1, 0), col=adjustcolor("white", alpha=0), border=NA)
            #   polygon(x=c(-1,-1, break_two , break_two), y=c(-1.1, .1, .1, -1.1), col=adjustcolor("white", alpha=0.8), border=NA) 
                #abline(v= break_one, col="white")
                #abline(v= break_two, col="white")
                
#lines(x=c(break_one_2, break_one_2), y=c(1,3), col="white")
#lines(x=c(break_one_1, break_one_1), y=c(1,-1), col="white")
#lines(x=c(break_two_2, break_two_2), y=c(1,3), col="white")
#lines(x=c(break_two_1, break_two_1), y=c(1,-1), col="white") 
#lines(4:21, meanss)
    #lines(21:4, meanss)
    
}
frameplot()
complex_figure(1,names(per.origin)[2], 1, global.means, global.SD) 
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:11] =      0,   0.25,   1.25,  ...,   6.75,   7.75
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:11] =      0,   2.25,   2.75,  ...,   5.75,   6.25
axis(1)
axis(2)

Assemble the figure

Assemble the figure

quartz(width=8, height=8)
layout(matrix(c(
    1, 1, 1, 1, 1, 1, 1, 1,
    3,  6, 7, 8, 9, 10, 11, 4, 
    3,  5, 5, 5, 5, 5, 5,   4, 
    3,  12, 13, 14, 15, 16, 17, 4,
    2, 2, 2, 2, 2, 2, 2, 2
    ), 5, 8, byrow=TRUE), width=c(1, 1, 1, 1, 1, 1, 1, 1), height=c(0.7, 1, 1.5, 1, 0.7))
par(mar=c(0,0,0,0))
# 1-4 label margins
blankplot <- function(){
    
    plot(0,0, xlim=c(4,21), ylim=c(1, 1.25), bty="n", type="n", xaxt="n", yaxt="n", xlab="", ylab="")
}
blankplot()
blankplot()
blankplot()
blankplot()
d <- readPNG("40962.png")
dim(d)
[1] 1000 2000    4
par(mar=c(0,0,0,0))
plot(0:360,0:360,type="n",xlim=c(20,360),ylim=c(65,295), yaxt="n", xaxt="n")
rasterImage(d, -28.5, -13.5, 388, 375, interpolate=TRUE, col=d)
axis(2, label=seq(-90, 90, length.out = 19), at=seq(1, 360, length.out = 19), las=1)
mtext("latitude", 2, line=4, at=180)
abline(h=seq(1, 360, length.out = 19), col=adjustcolor("grey10", alpha= 0.4), lwd=1)
abline(h=180, col=adjustcolor("white", alpha= .5), lwd=1)
load('PopD_all_December.rdata')
# Extract the data
prod.origin <- extract(PopD.ALL, origins_subset)
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
NOTE: rgdal::checkCRSArgs: no proj_defs.dat in PROJ.4 shared files
library(matrixStats)
# Mean and SD per region
means <- lapply(prod.origin, colMeans, na.rm = TRUE)
sds <- lapply(prod.origin, colSds, na.rm = TRUE)
## new values from Bruno's GAM model (produced in script called Population_Trend_per_y.R)
for_3 <- diff_df(3)
global.means <- for_3[[1]]
global.SD <- for_3[[2]]
means <- global.means
sds <- global.gams
names(means) <- origins_subset@data$CONTINENT
ymax <- max(unlist(means))
ymin <- min(unlist(means))
time <- 4:21
#plot(origins)
#means[[1]] +
#sds[[1]]
#scale(as.numeric(means[[1]]), center=FALSE)
name_vector <- as.character(origins_subset@data$CONTINENT)
for(i in 1:12){
    
    if(i > 6){frameplot()}else{frameplot_bottom()}
    
        ## customize polygons for each graph
    if(i == 1){ #mesoamerica  #values from Larson
        
            complex_figure(3, "Mesoamerica", i, means, sds)
                
    
        }
    
    
    #########
    if(i == 2 ){ #NW lowlands SA  #values from Larson
        
        complex_figure(6, "NW_Lowland_SA", i, means, sds)
    
        }
        
        #########
    if( i == 3){ #NW lowlands SA  #values from Larson
        
        complex_figure(6, "N_Lowland_SA", i, means, sds)
        
        }
        #########
    if(i == 4){ #Fertile crescent aka Southwest asia  #values from Larson
        
        
    complex_figure(8, "Fertile_Cresc", i, means, sds)
                
        }
        
        #########
    if(i == 5){ #loess plateau  #values from Larson
        
        complex_figure(2, "Chinese_loess", i, means, sds)
            
        }
        
        
        #########
    if(i == 6){ #new guinea  #values from Larson
        
        complex_figure(4, "New_Guinea", i, means, sds)
        
        }
#########
    if(i == 7){ #Eastern N.A.  #values from Larson
        
        complex_figure(5, "E_North_Ameri", i, means, sds)
        
            }
        #########
    if(i == 8){ #Andes  #values from Larson
        
        complex_figure(6, "C/S_Andes", i, means, sds)
        
                }
#########
    if(i == 9){ #W. African Sav  #values from Larson
        
        complex_figure(1, "W_African_Sav", i, means, sds)
        
            }
#########
    if(i == 10){ #Sudanic sav  #values from Larson
        
        complex_figure(1, "Sudanic_Savan", i, means, sds)
        
                }
#########
    if(i == 11){ #Ganges  #values from Larson
        
        
        complex_figure(7, "Ganges_E_Indi", i, means, sds) 
        
        }
#########
    if(i == 12){ #"Lower-MiddleY"  #values from Larson
        
        complex_figure(2, "Lower-MiddleY", i, means, sds)
         
                }
        
        
        #lines(4:21, means[[i]])
        
        #abline(h = 1, col=adjustcolor("forestgreen", alpha=.5), lty=2)
        
    # add axes to some locations
    if(i == 1 | i == 7){axis(2, at=seq(-2,2, by=0.5), label=seq(-2,2, by=0.5), las=1)}
    if(i == 6 | i == 12){axis(4, at=seq(-2,2, by=0.5), label=seq(-2,2, by=0.5), las=1)}
    #if(i == 6 | i == 12){axis(4, at=seq(2,3, by=0.25), label=seq(0,1, by=0.25), las=1)
    #   axis(4, at=seq(-1,0, by=0.25), label=rev(seq(0,1, by=0.25)), las=1)
    #   }
    if(i > 6){axis(1)} else{axis(3)}
    
    # add text 
    if(i < 7){polygon(x=c(-30, -30, 30, 30), y=c(-3.1, -3.5, -3.5, -3.1), col="black")
    mtext(name_vector[i], 1, line=-0.9, col="white", cex=0.5)}
    
    if(i > 6){polygon(x=c(-30, -30, 30, 30), y=c(2.1, 2.5, 2.5, 2.1), col="black")
    mtext(name_vector[i], 3, line=-0.8, col="white", cex=0.5)}
    
    # add axis labels
    if(i == 1 | i ==  7){mtext("scaled density potential", 2, line=4, at=1)}
    if(i ==  3){mtext("Thousand years before present", 3, line=3.5, at =5)}
    if(i ==  9){mtext("Thousand years before present", 1, line=3.5, at =5)
        
        }
    
}
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:4] =      0,      4,      7,      8
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:5] =      0,      1,      4,      7,      8
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:8] =      0,      1,      2,  ...,      5,      6
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:9] =      0,      1,      2,  ...,      6,    6.5
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:8] =      0,      1,      2,  ...,      5,      6
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:9] =      0,      1,      2,  ...,      6,    6.5
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:6] =      0,    0.5,      1,  ...,      2,      8
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:8] =      0,    0.5,   0.75,  ...,      5,      7
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:11] =      0,    0.5,      2,  ...,   7.75,    9.5
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:9] =      0,    0.5,      1,  ...,    4.5,    7.5
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:1] =      0
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:2] =      0,      4
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:3] =      0,    0.5,   1.75
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:3] =      0,      1,   1.25
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:8] =      0,      1,      2,  ...,      5,      6
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:9] =      0,      1,      2,  ...,      6,    6.5
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:11] =      0,   0.25,   1.25,  ...,   6.75,   7.75
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:11] =      0,   2.25,   2.75,  ...,   5.75,   6.25
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:11] =      0,   0.25,   1.25,  ...,   6.75,   7.75
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:11] =      0,   2.25,   2.75,  ...,   5.75,   6.25
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:7] =      0,    0.5,      1,  ...,      5,    5.5
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:4] =      0,    3.5,      4,    4.5
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:11] =      0,    0.5,      2,  ...,   7.75,    9.5
Empirical CDF 
Call: ecdf(maxer - match)
 x[1:9] =      0,    0.5,      1,  ...,    4.5,    7.5
saveToPDF <- function(...) {
    d = dev.copy(pdf,...)
    dev.off(d)
}
saveToPNG <- function(...) {
    d = dev.copy(png,...)
    dev.off(d)
}
## Try them out
saveToPDF("my.pdf", height=8,width=8)
quartz 
     2 
saveToPNG("my.png", height=8, width=8, units="in", res=300)
quartz 
     2 
dev.off()
null device 
          1 
LS0tCnRpdGxlOiAiT3JpZ2lucyBvZiBhZ3JpY3VsdHVyZSBkZW5zaXR5IGFuYWx5c2lzIgphdXRob3I6ICJUeSBUdWZmIgpkYXRlOiAncHJvamVjdCBiZWdhbjogU2VwdGVtYmVyIDIwMTYsIGRvY3VtZW50IHVwZGF0ZWQ6IGByIHN0cmZ0aW1lKFN5cy50aW1lKCksIGZvcm1hdAogID0gIiVkICVCICVZIilgJwpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAogIHdvcmRfZG9jdW1lbnQ6IGRlZmF1bHQKLS0tCiMjIEN1cnJlbnQgYmVzdCB2ZXJzaW9uCiFbRmlndXJlIDEgLSBUaGlzIGZpZ3VyZXMgc2hvd3MuLi5dKG15LnBuZykKCgoKCgojIyBDb2RlCjEuIFtSIGVudmlyb25tZW50IHNldHVwXSgjci1lbnZpcm9ubWVudC1zZXR1cCkKMi4gW1NldHRpbmcgdGltZSBicmVha3NdKCNzZXR0aW5nLXRpbWUtYnJlYWtzKQozLiBbRGVmaW5pbmcgb3JpZ2luc10oI2RlZmluaW5nLW9yaWdpbnMpCjQuIFtJbXBvcnQgcmFzdGVyIGRhdGFdKCNpbXBvcnQtcmFzdGVyLWRhdGEpCjUuIFtHQU0gc21vb3RoaW5nIG1vZGVsc10oI2dhbS1zbW9vdGhpbmctbW9kZWxzKQo2LiBbQ29tcGFyZSByYXRlcyBiZXR3ZWVuIG9yaWdpbnMgYW5kIG5vdC1vcmlnaW5zXSgjY29tcGFyZS1yYXRlcy1iZXR3ZWVuLW9yaWdpbnMtYW5kLW5vdC1vcmlnaW5zKQo3LiBbQ29tcGFyZSByYXRlcyBiZXR3ZWVuIGRpZmZlcmVudCB0aW1lIHBlcmlvZHNdKCNjb21wYXJlLXJhdGVzLWJldHdlZW4tZGlmZmVyZW50LXRpbWUtcGVyaW9kcykKOC4gW1NldHVwIGZpbmFsIGZpZ3VyZV0oI3NldHVwLWZpbmFsLWZpZ3VyZSkKOS4gW01hcCBmb3IgZmluYWwgZmlndXJlXSgjbWFwLWZvci1maW5hbC1maWd1cmUpCjEwLiBbVHJlbmQgdGhyb3VnaCB0aW1lIHBhbmVsIGZvciBmaW5hbCBmaWd1cmVdKCN0cmVuZC10aHJvdWdoLXRpbWUtcGFuZWwpCjExLiBbQXNzZW1ibGUgYW5kIHByaW50IGZpbmFsIGZpZ3VyZV0oI2Fzc2VtYmxlLXRoZS1maWd1cmUpCgoKCiMjIFIgZW52aXJvbm1lbnQgc2V0dXAKIyMjIyBBdHRhY2ggbGlicmFyaWVzCmBgYHtyfQpsaWJyYXJ5KHBuZykKbGlicmFyeShtYXB0b29scykKbGlicmFyeShyYXN0ZXIpCmxpYnJhcnkoZ2FtKQoKbGlicmFyeShtYXBwcm9qKQpsaWJyYXJ5KHJnbCkKYGBgCgoKCiMjIyMgU2V0IHdvcmtpbmcgZGlyZWN0b3J5CmBgYHtyfQpzZXR3ZCgifi9EZXNrdG9wL0JvdGVybyBwb3N0ZG9jIDIwMTYvSHVtYW4gZGVuc2l0eSBhbmQgdGhlIG9yaWdpbnMgb2YgYWdyaWN1bHR1cmUvIikKYGBgCgoKCiMjIFNldHRpbmcgdGltZSBicmVha3MKIyMjIyBEZWZpbmUgdGhlIHRpbWVzIG9mIGFncmljdWx0dXJhbCBvcmlnaW5zCiFbXShMYXJzb25fZGF0ZXMuanBnKQoKYGBge3J9CnBhcihtYXI9YygwLDAsMCwyMCkpCmQgPC0gcmVhZFBORygiTGFyc29uX2RhdGVzLnBuZyIpCnBsb3Qoc2VxKDAsMTgsIGxlbmd0aC5vdXQgPSAxOSksIHNlcSgwLDM2LCBsZW5ndGgub3V0ID0gMTkpLCB0eXBlPSJuIix5bGltPWMoMCwzNikseGxpbT1jKDAsIDE4KSwgeGF4dD0ibiIpCgpyYXN0ZXJJbWFnZShkLCAwLDAsMTgsMzYsIGludGVycG9sYXRlPVRSVUUsIGNvbD1kKQoKCgpTdGFydF9vZl9lYXJseV93aW5kb3cgPC0gMTYtMTIKRW5kX29mX2Vhcmx5X3dpbmRvd19zdGFydF9vZl9sYXRlX3dpbmRvdyA8LSA4LjIKRW5kX29mX2xhdGVfd2luZG93IDwtIDE3LTQuMgoKcG9seWdvbih4PWMoU3RhcnRfb2ZfZWFybHlfd2luZG93LCBTdGFydF9vZl9lYXJseV93aW5kb3csIEVuZF9vZl9lYXJseV93aW5kb3dfc3RhcnRfb2ZfbGF0ZV93aW5kb3csIEVuZF9vZl9lYXJseV93aW5kb3dfc3RhcnRfb2ZfbGF0ZV93aW5kb3cpLCB5PWMoMCwgMzQsIDM0LCAwKSwgY29sPWFkanVzdGNvbG9yKCJsaW1lZ3JlZW4iLCBhbHBoYT0gMC4yKSwgYm9yZGVyPWFkanVzdGNvbG9yKCJsaW1lZ3JlZW4iLCBhbHBoYT0gMC45KSkKCnBvbHlnb24oeD1jKCBFbmRfb2ZfZWFybHlfd2luZG93X3N0YXJ0X29mX2xhdGVfd2luZG93LCBFbmRfb2ZfZWFybHlfd2luZG93X3N0YXJ0X29mX2xhdGVfd2luZG93LCBFbmRfb2ZfbGF0ZV93aW5kb3csIEVuZF9vZl9sYXRlX3dpbmRvdyksIHk9YygwLCAzNCwgMzQsIDApLCBjb2w9YWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPSAwLjIpLCBib3JkZXI9YWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPSAwLjkpKQoKYGBgCgoKClRoZXNlIGRhdGVzIGFyZSBwcm92aWRlZCBpbiB0aGUgc3VwcGxpbWVudGFyeSBpbmZvcm1hdGlvbiBmb3IgdGhlIExhcnNvbiAoMjAxNCkgcGFwZXIuIEkndmUgY29waWVkIHRob3NlIHZhbHVlcyBpbnRvIGEgLmNzdiB0YWJsZSBwcm92aWRlZCBoZXJlLiAKCmBgYHtyfQpkb21lc3RpY2F0aW9uX3RpbWVzIDwtIHJlYWQuY3N2KCJEb21lc3RpY2F0aW9uIHRpbWluZyBsYXJzb24gMjAxNC5jc3YiKQoKZGltKGRvbWVzdGljYXRpb25fdGltZXMpCmBgYAoKYGBge3IsIGVjaG89RkFMU0V9CmxpYnJhcnkoa25pdHIpIAprYWJsZShkb21lc3RpY2F0aW9uX3RpbWVzLCBjYXB0aW9uPSAiVGhpcyBpcyBvdXIgd29ybGQiKQpgYGAKCgpgYGB7cn0KcGFyKG1hcj1jKDUsNCw2LDEpKQoKZGF0ZXMgPC0gdW5saXN0KGRvbWVzdGljYXRpb25fdGltZXNbMzo4XSkKaGlzdChkYXRlcywgYnJlYWtzID0gMjIsIHhsaW09YygxNSwwKSwgeGxhYj0iSyB5ZWFycyBhZ28iLCBjb2w9YWRqdXN0Y29sb3IoImNvcm5mbG93ZXJibHVlIiwgYWxwaGE9IDAuNSksIGJvcmRlcj1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCBhbHBoYT0gMC45KSwgbWFpbj0iQWxsIGRhdGVzIGluIGRhdGFzZXQiICApCm10ZXh0KCJUaGlzIHRlbGxzIHVzIGFib3V0IGhvdyBldmVubHkgb3VyIGV2aWRlbmNlIGlzIGRpc3RyaWJ1dGVkIGluIHRpbWUiLCAzLCBsaW5lPTEpCgoKYGBgCgpgYGB7cn0KaGlzdChkYXRlcywgYnJlYWtzID0gMjIsIHhsaW09YygxNSwwKSwgeGxhYj0iVGhvdXNhbmQgeWVhcnMgYWdvIiwgY29sPWFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIGFscGhhPSAwLjUpLCBib3JkZXI9YWRqdXN0Y29sb3IoImNvcm5mbG93ZXJibHVlIiwgYWxwaGE9IDAuOSksIG1haW49IkFsbCBkYXRlcyBpbiBkYXRhc2V0IHdpdGggTGFyc29uKDIwMTQpIGRhdGUgd2luZG93cyIpCgpTdGFydF9vZl9lYXJseV93aW5kb3cgPC0gMTIKRW5kX29mX2Vhcmx5X3dpbmRvd19zdGFydF9vZl9sYXRlX3dpbmRvdyA8LSA4LjIKRW5kX29mX2xhdGVfd2luZG93IDwtIDQuMgoKcG9seWdvbih4PWMoU3RhcnRfb2ZfZWFybHlfd2luZG93LCBTdGFydF9vZl9lYXJseV93aW5kb3csIEVuZF9vZl9lYXJseV93aW5kb3dfc3RhcnRfb2ZfbGF0ZV93aW5kb3csIEVuZF9vZl9lYXJseV93aW5kb3dfc3RhcnRfb2ZfbGF0ZV93aW5kb3cpLCB5PWMoMCwgMzAsIDMwLCAwKSwgY29sPWFkanVzdGNvbG9yKCJsaW1lZ3JlZW4iLCBhbHBoYT0gMC4yKSwgYm9yZGVyPWFkanVzdGNvbG9yKCJsaW1lZ3JlZW4iLCBhbHBoYT0gMC45KSkKCnBvbHlnb24oeD1jKCBFbmRfb2ZfZWFybHlfd2luZG93X3N0YXJ0X29mX2xhdGVfd2luZG93LCBFbmRfb2ZfZWFybHlfd2luZG93X3N0YXJ0X29mX2xhdGVfd2luZG93LCBFbmRfb2ZfbGF0ZV93aW5kb3csIEVuZF9vZl9sYXRlX3dpbmRvdyksIHk9YygwLCAzMCwgMzAsIDApLCBjb2w9YWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPSAwLjIpLCBib3JkZXI9YWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPSAwLjkpKQoKaGlzdChkYXRlcywgYnJlYWtzID0gMjIsIHhsaW09YygxNSwwKSwgeGxhYj0iSyB5ZWFycyBhZ28iLCBjb2w9YWRqdXN0Y29sb3IoImNvcm5mbG93ZXJibHVlIiwgYWxwaGE9IDAuMiksIGJvcmRlcj1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCBhbHBoYT0gMC45KSwgbWFpbj0iIiwgYWRkPVRSVUUpCgptdGV4dCgiRWFybHkgSG9sb2NlbmUiLCAzLCBsaW5lID0gLTEsIGFkaj0uMykKbXRleHQoIk1pZGRsZSBIb2xvY2VuZSIsIDMsIGxpbmU9IC0xLCBhZGo9LjYpCgpgYGAKCmBgYHtyfQoKcGFyKG1mcm93PWMoMiwzKSwgbWFyPWMoNCw0LDIsMCkpCmRpbShkb21lc3RpY2F0aW9uX3RpbWVzKQpzcGVjaWZpY19kYXRlcyA8LSBkb21lc3RpY2F0aW9uX3RpbWVzWywzOjhdCgpmb3IoaSBpbiBjKDEsIDMsIDUsIDIsIDQsIDYpKXsKaGlzdChzcGVjaWZpY19kYXRlc1ssaV0sIGJyZWFrcyA9IDIyLCB4bGltPWMoMTUsMCksIHhsYWI9IlRob3VzYW5kIHllYXJzIGFnbyIsIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCBhbHBoYT0gMC41KSwgYm9yZGVyPWFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIGFscGhhPSAwLjkpLCBtYWluPSBuYW1lcyhzcGVjaWZpY19kYXRlcylbaV0pCgpTdGFydF9vZl9lYXJseV93aW5kb3cgPC0gMTIKRW5kX29mX2Vhcmx5X3dpbmRvd19zdGFydF9vZl9sYXRlX3dpbmRvdyA8LSA4LjIKRW5kX29mX2xhdGVfd2luZG93IDwtIDQuMgoKcG9seWdvbih4PWMoU3RhcnRfb2ZfZWFybHlfd2luZG93LCBTdGFydF9vZl9lYXJseV93aW5kb3csIEVuZF9vZl9lYXJseV93aW5kb3dfc3RhcnRfb2ZfbGF0ZV93aW5kb3csIEVuZF9vZl9lYXJseV93aW5kb3dfc3RhcnRfb2ZfbGF0ZV93aW5kb3cpLCB5PWMoMCwgMzAsIDMwLCAwKSwgY29sPWFkanVzdGNvbG9yKCJsaW1lZ3JlZW4iLCBhbHBoYT0gMC4yKSwgYm9yZGVyPWFkanVzdGNvbG9yKCJsaW1lZ3JlZW4iLCBhbHBoYT0gMC45KSkKCnBvbHlnb24oeD1jKCBFbmRfb2ZfZWFybHlfd2luZG93X3N0YXJ0X29mX2xhdGVfd2luZG93LCBFbmRfb2ZfZWFybHlfd2luZG93X3N0YXJ0X29mX2xhdGVfd2luZG93LCBFbmRfb2ZfbGF0ZV93aW5kb3csIEVuZF9vZl9sYXRlX3dpbmRvdyksIHk9YygwLCAzMCwgMzAsIDApLCBjb2w9YWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPSAwLjIpLCBib3JkZXI9YWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPSAwLjkpKQoKaGlzdChzcGVjaWZpY19kYXRlc1ssaV0sIGJyZWFrcyA9IDIyLCB4bGltPWMoMTUsMCksIHhsYWI9IksgeWVhcnMgYWdvIiwgY29sPWFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIGFscGhhPSAwLjIpLCBib3JkZXI9YWRqdXN0Y29sb3IoImNvcm5mbG93ZXJibHVlIiwgYWxwaGE9IDAuOSksIG1haW49IiIsIGFkZD1UUlVFKQp9CmBgYAoKCkknbSBjcmVhdGluZyBuZXcgcm93cyBmb3IgdGhpcyB0YWJsZSwgY29tYmluaW5nIGRhdGVzIGluIGRpZmZlcmVudCB3YXlzIHRvIG1ha2UgdGhlIENERnMgYmVsb3cgbG9vayBtb3JlIGF1dGhlbnRpYy4gVGhpcyBtYWtlcyBpdCBzbyB0aGF0IHByZS1hZyBhbHdheXMgaGFwcGVucyBiZWZvcmUgcG9zdC1hZy4gV2hhdCBJJ3ZlIGRvbmUgaXMgZ2l2ZW4gdGhlIGxhdGVyIGRhdGUgdG8gdGhlIGVhcmxpZXIgZGF0ZSB3aGVuIHRob3NlIGRhdGVzIGFyZSBtaXNzaW5nLiAKYGBge3J9CmggPC0gd2hpY2goaXMubmEoZG9tZXN0aWNhdGlvbl90aW1lc1ssM10pKQpkb21lc3RpY2F0aW9uX3RpbWVzIDwtIGNiaW5kKGRvbWVzdGljYXRpb25fdGltZXMsIHJlcChOQSwgbGVuZ3RoKGRvbWVzdGljYXRpb25fdGltZXNbLDFdKSkpCmRvbWVzdGljYXRpb25fdGltZXNbLDldIDwtIGRvbWVzdGljYXRpb25fdGltZXNbLDNdCmRvbWVzdGljYXRpb25fdGltZXNbaCw5XSA8LSBkb21lc3RpY2F0aW9uX3RpbWVzW2gsN10KY29sbmFtZXMoZG9tZXN0aWNhdGlvbl90aW1lcylbOV0gPC0gImFkb3B0IGV4cGxvaXRhdGlvbiBkYXRlIgpkb21lc3RpY2F0aW9uX3RpbWVzWywxMF0gPC0gZG9tZXN0aWNhdGlvbl90aW1lc1ssN10KZG9tZXN0aWNhdGlvbl90aW1lc1t3aGljaChpcy5uYShkb21lc3RpY2F0aW9uX3RpbWVzWywxMF0pKSwxMF0gPC0gMApjb2xuYW1lcyhkb21lc3RpY2F0aW9uX3RpbWVzKVsxMF0gPC0gInN0YXJ0IG9mIGFnIgojc2F2ZShkb21lc3RpY2F0aW9uX3RpbWVzLCBmaWxlPSJ+L0Rlc2t0b3AvSHVtYW4gZGVuc2l0eSBhbmQgdGhlIG9yaWdpbnMgb2YgYWdyaWN1bHR1cmUvRG9tZXN0aWNhdGlvbiB0aW1pbmcgbGFyc29uIDIwMTQuUmRhdGEiKQpgYGAKCgoKSSB0aGluayB0aGVzZSBhcmUgYmVzdCBkZXNjcmliZWQgYnkgYSBjdW1tdWxhdGl2ZSBkaXN0cmlidXRpb24sIHNob3dpbmcgaG93IHRoZXkgYWNjdW11bGF0ZSBvdmVyIHRpbWUuIAoKYGBge3J9CmZvcihpIGluIDE6OCl7CnR5cGVfbnVtYmVyIDwtIGkKCW1hdGNoIDwtIGRvbWVzdGljYXRpb25fdGltZXNbIHdoaWNoKGRvbWVzdGljYXRpb25fdGltZXMkUmVnaW9uID09IGxldmVscyhkb21lc3RpY2F0aW9uX3RpbWVzJFJlZ2lvbilbIHR5cGVfbnVtYmVyXSksIDldCgltYXhlciA8LSBtYXgobWF0Y2gsIG5hLnJtPVRSVUUpCglqIDwtIGVjZGYobWF4ZXItbWF0Y2gpCglwcmludChsZXZlbHMoZG9tZXN0aWNhdGlvbl90aW1lcyRSZWdpb24pWyB0eXBlX251bWJlcl0pCglwcmludChtYXRjaCkKCXByaW50KGopCn0KYGBgCgoKCmBgYHtyfQpwYXIobWZjb2w9YygyLDUpLCBtYXI9Yyg0LDAsNSwwKSkKCnBsb3QoMCwwLCB0eXBlPSJuIiwgeGF4dD0ibiIsIHhsYWI9IiIsIGJ0eT0ibiIpCm10ZXh0KCJQZXJjZW50IG9mIHNwZWNpZXMgdGhhdCB3aWxsIGV2ZW50dWFsbHkgXG4gYmUgZG9tZXN0aWNhdGVkIGluIGEgcmVnaW9uIiwgMiwgbGluZT0tNSwgY2V4PTAuNSkKcGxvdCgwLDAsIHR5cGU9Im4iLCB4YXh0PSJuIiwgeGxhYj0iIiwgYnR5PSJuIikKbXRleHQoIlBlcmNlbnQgb2Ygc3BlY2llcyB0aGF0IHdpbGwgZXZlbnR1YWxseSBcbiBiZSBkb21lc3RpY2F0ZWQgaW4gYSByZWdpb24iLCAyLCBsaW5lPS01LCBjZXg9MC41KQoKZm9yKGkgaW4gMTo4KXsKdHlwZV9udW1iZXIgPC0gaQoJbWF0Y2ggPC0gZG9tZXN0aWNhdGlvbl90aW1lc1sgd2hpY2goZG9tZXN0aWNhdGlvbl90aW1lcyRSZWdpb24gPT0gbGV2ZWxzKGRvbWVzdGljYXRpb25fdGltZXMkUmVnaW9uKVsgdHlwZV9udW1iZXJdKSwgOV0KCW1heGVyIDwtIG1heChtYXRjaCwgbmEucm09VFJVRSkKCWogPC0gZWNkZihtYXhlci1tYXRjaCkKCSNwcmludChqKQoJCnBsb3QoMCwwLCB4bGltPWMoMTUsMCksIHlsaW09YygwLDEwMCksIHlsYWI9IlBlcmNlbnQgb2Ygc3BlY2llcyB0aGF0IHdpbGwgZXZlbnR1YWxseSBcbiBiZSBkb21lc3RpY2F0ZWQgaW4gYSByZWdpb24iLCB4bGFiPSJUaG91c2FuZCB5ZWFycyBhZ28iLCBtYWluPWxldmVscyhkb21lc3RpY2F0aW9uX3RpbWVzJFJlZ2lvbilbIHR5cGVfbnVtYmVyXSwgdHlwZT0ibiIsIHlheHQ9Im4iKQoKeF9zZXEgPC0gcmV2KGMoMCxzZXEoMCwgbWF4ZXIsIGxlbmd0aC5vdXQ9MTAwKSkpCnlfc2VxIDwtIDEwMCAqIChjKDAsIGooc2VxKDAsIG1heGVyLCBsZW5ndGgub3V0PTEwMCkpKSkKCmxpbmVzKHhfc2VxLCB5X3NlcSwgIHlsaW09YygtMSwxKSkKcG9seWdvbihjKDAsIHhfc2VxKSwgYygwLCB5X3NlcSksIGJvcmRlcj1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLGFscGhhPTEpLCBjb2w9YWRqdXN0Y29sb3IoImNvcm5mbG93ZXJibHVlIiwgYWxwaGE9MC4yKSkKaWYoaSA9PSAyIHwgaSA9PSAxKWF4aXMoMikKCmlmKGkgPT0gMyltdGV4dCgiQ3VtbXVsYXRpdmUgZGlzdHJpYnV0aW9uIGZ1bmN0aW9uIGZvciB0aGUgYWNjdW11bGF0aW9uIG9mIGRvbWVzdGljYXRlcyIsIDMsIGxpbmU9My44LCBjb2w9ImNvcm5mbG93ZXJibHVlIikKfQoKCmBgYAoKCmBgYHtyfQpwYXIobWZjb2w9YygyLDUpLCBtYXI9Yyg0LDAsNSwwKSkKCnBsb3QoMCwwLCB0eXBlPSJuIiwgeGF4dD0ibiIsIHhsYWI9IiIsIGJ0eT0ibiIpCm10ZXh0KCJQZXJjZW50IG9mIHNwZWNpZXMgdGhhdCB3aWxsIGV2ZW50dWFsbHkgXG4gYmUgZG9tZXN0aWNhdGVkIGluIGEgcmVnaW9uIiwgMiwgbGluZT0tNSwgY2V4PTAuNSkKCnBsb3QoMCwwLCB0eXBlPSJuIiwgeGF4dD0ibiIsIHhsYWI9IiIsIGJ0eT0ibiIpCm10ZXh0KCJQZXJjZW50IG9mIHNwZWNpZXMgdGhhdCB3aWxsIGV2ZW50dWFsbHkgXG4gYmUgZG9tZXN0aWNhdGVkIGluIGEgcmVnaW9uIiwgMiwgbGluZT0tNSwgY2V4PTAuNSkKCmZvcihpIGluIDE6OCl7CnR5cGVfbnVtYmVyIDwtIGkKCW1hdGNoIDwtIGRvbWVzdGljYXRpb25fdGltZXNbIHdoaWNoKGRvbWVzdGljYXRpb25fdGltZXMkUmVnaW9uID09IGxldmVscyhkb21lc3RpY2F0aW9uX3RpbWVzJFJlZ2lvbilbIHR5cGVfbnVtYmVyXSksIDldCgltYXhlciA8LSBtYXgobWF0Y2gsIG5hLnJtPVRSVUUpCglqIDwtIGVjZGYobWF4ZXItbWF0Y2gpCgkjcHJpbnQoaikKCQpwbG90KDAsMCwgeGxpbT1jKDE1LDApLCB5bGltPWMoMCwxMDApLCB5bGFiPSJQZXJjZW50IG9mIHNwZWNpZXMgdGhhdCB3aWxsIGV2ZW50dWFsbHkgXG4gYmUgZG9tZXN0aWNhdGVkIGluIGEgcmVnaW9uIiwgeGxhYj0iVGhvdXNhbmQgeWVhcnMgYWdvIiwgbWFpbj1sZXZlbHMoZG9tZXN0aWNhdGlvbl90aW1lcyRSZWdpb24pWyB0eXBlX251bWJlcl0sIHR5cGU9Im4iLCB5YXh0PSJuIikKCnhfc2VxIDwtIHJldihjKDAsc2VxKDAsIG1heGVyLCBsZW5ndGgub3V0PTEwMCkpKQp5X3NlcSA8LSAxMDAgKiAoYygwLCBqKHNlcSgwLCBtYXhlciwgbGVuZ3RoLm91dD0xMDApKSkpCgpsaW5lcyh4X3NlcSwgeV9zZXEsICB5bGltPWMoLTEsMSkpCnBvbHlnb24oYygwLCB4X3NlcSksIGMoMCwgeV9zZXEpLCBib3JkZXI9YWRqdXN0Y29sb3IoImNvcm5mbG93ZXJibHVlIixhbHBoYT0xKSwgY29sPWFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIGFscGhhPTAuMikpCmFibGluZSh2PSBtYXhlciAtIHF1YW50aWxlKGopWzJdLCBjb2w9ImxpbWVncmVlbiIsIGx3ZD0yKQppZihpID09IDIgfCBpID09IDEpYXhpcygyKQppZihpID09IDIpbXRleHQoIjI1JSIsIDMsIGxpbmU9My41LCBhZGo9LTEsIGNvbD0ibGltZWdyZWVuIikKaWYoaSA9PSAzKW10ZXh0KCJDdW1tdWxhdGl2ZSBkaXN0cmlidXRpb24gZnVuY3Rpb24gZm9yIHRoZSBhY2N1bXVsYXRpb24gb2YgZG9tZXN0aWNhdGVzIiwgMywgbGluZT0zLjgsIGNvbD0iY29ybmZsb3dlcmJsdWUiKQppZihpID09IDQpbXRleHQoIkNob29zZSBhIHkgdG8gcHJlZGljdCBhbiB4IiwgMywgbGluZT0zLjMsIGNvbD0iY29ybmZsb3dlcmJsdWUiKQoJYnJlYWtfb25lIDwtIG1heGVyCgkJCWJyZWFrX3R3byA8LSBtYXhlciAtIHF1YW50aWxlKGopWzJdCgkJCQkKCXBvbHlnb24oeD1jKGJyZWFrX3R3bywgYnJlYWtfdHdvLCBicmVha19vbmUsIGJyZWFrX29uZSksIHk9YygwLCAxLCAxLCAwKSwgY29sPWFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIGFscGhhPTAuMiksIGJvcmRlcj1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLGFscGhhPTEpKQoJCQlsaW5lcyh4PWMoYnJlYWtfdHdvLCBicmVha190d28pLCB5PWMoMCwtMSksIGNvbD0iY29ybmZsb3dlcmJsdWUiKQoJCQlhYmxpbmUoaCA9IDI1LCBjb2w9ImxpbWVncmVlbiIsIGx3ZD0yKQp9CgoKYGBgCk1ha2UgdGhpcyBhIGZ1bmN0aW9uLiAKVGhlcmUgaXMgYSBjaG9pY2Ugb2YgdHdvIG1ldGhvZHMgaGVyZS4gQXQgdGhlIGVuZCBvZiB0aGlzIHNlY3Rpb24gd2UgbmVlZCB0byBwcmludCB0aGUgZGVzaXNpb24gd2UncmUgcGFzc2luZyB0byB0aGUgbGF0ZXIgYW5hbHlzZXMuIAoKCgoKCgojIyBEZWZpbmluZyBvcmlnaW5zCiFbXShMYXJzb25fb3JpZ2lucy5qcGcpCgpgYGB7cn0KbGlicmFyeShtYXBzKQptYXAoKQptYXAob3JpZ2lucywgYWRkPVRSVUUsIGZpbGw9VFJVRSwgY29sPWFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIGFscGhhPTEpKQoKYGBgCgoKYGBge3J9Cm1hcCgpCmQgPC0gcmVhZFBORygiTGFyc29uX29yaWdpbnMucG5nIikKcmFzdGVySW1hZ2UoZCwgLTE4MCwgLTkwLCAxODAsIDExMCwgaW50ZXJwb2xhdGU9VFJVRSwgY29sPWQpCm1hcChhZGQ9VFJVRSkKbWFwKG9yaWdpbnMsIGFkZD1UUlVFLCBmaWxsPVRSVUUsIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCBhbHBoYT0xKSkKCiMgbmVlZCB0byByZXByb2plY3QKYGBgClRoaXMgaXMgb2J2aW91c2x5IGEgYmFkIHByb2plY3Rpb24gZml0IHJpZ2h0IG5vdy4gCgojI21hcCBmb3IgZmluYWwgZmlndXJlCgoKCmBgYHtyfQpvcmlnaW5zIDwtIHJlYWRTaGFwZVBvbHkoJ09yaWdpbnNfdXBkYXRlZC5zaHAnKQpwcm9qNHN0cmluZyhvcmlnaW5zKSA8LSBDUlMoIitwcm9qPWxvbmdsYXQgK2RhdHVtPVdHUzg0IikKI3Byb2ogPC0gQ1JTKCIrcHJvaj1lcWMgK2xhdF90cz0wICtsYXRfMD0wICtsb25fMD0wICt4XzA9MCAreV8wPTAgK2VsbHBzPVdHUzg0ICt1bml0cz1tICtub19kZWZzIikKI29yaWdpbnMuZWEgPC0gc3BUcmFuc2Zvcm0ob3JpZ2lucywgcHJvaikKCgojc3Vic2V0X29yZGVyIDwtIGMoMSwgMiwgMywgNSwgNiwgOCwgOSwgMTAsIDExLCAxMiwgMTcsIDE4KQpzdWJzZXRfb3JkZXIgPC0gYyg4LCAxMCwgOSwgNSwgMTgsIDcsIDYsIDIwLCAxLCAyLCAxMywgMTQpCm9yaWdpbnNfc3Vic2V0IDwtIG9yaWdpbnNbc3Vic2V0X29yZGVyLF0Kb3JpZ2luc19zdWJzZXQkQ09OVElORU5UCm9yaWdpbnNfc3Vic2V0JG5hbWUKCgpgYGAKCgojIyMjIE1ha2UgdGhlIG1hcCBmb3IgdGhlIGNlbnRlciBwYW5lbCAoIzUgb24gbGF5b3V0IHBhbmVsKQoKYGBge3J9CmQgPC0gcmVhZFBORygiZWFydGgucG5nIikKYGBgCgohW10oZWFydGgucG5nKQoKCgoKYGBge3J9CnBuZyhmaWxlPXBhc3RlKCI0MDk2Mi5wbmciLHNlcD0iIiksd2lkdGg9MjAwMCxoZWlnaHQ9MTAwMCwgYmc9InRyYW5zcGFyZW50IikKcGFyKG1hcj1jKDAsMCwwLDApKQpwbG90KHNlcSgtMTgwLCAxODAsIGxlbmd0aC5vdXQgPSAxOSksIHNlcSgtOTAsIDkwLCBsZW5ndGgub3V0ID0gMTkpLCB0eXBlPSJuIix4bGltPWMoLTE4MCwgMTgwKSx5bGltPWMoLTkwLCA5MCksIHhheHQ9Im4iKQoKcmFzdGVySW1hZ2UoZCwgLTE4MCwgLTkwLCAxODAsIDkwLCBpbnRlcnBvbGF0ZT1UUlVFLCBjb2w9ZCkKCnBvbHlnb24oeD1jKC0xODAsLTE4MCwgMTgwLDE4MCksIHk9YygtOTAsIDkwLCA5MCwgLTkwKSwgY29sPWFkanVzdGNvbG9yKCJ3aGl0ZSIsIGFscGhhPTAuMSkpCiNyYXN0ZXJJbWFnZShkLCAtMTMuNSwgLTEzLjUsIDM3NSwgMzc1LCBpbnRlcnBvbGF0ZT1UUlVFLCBjb2w9ZCkKcGxvdChvcmlnaW5zX3N1YnNldCwgYWRkPVRSVUUsIGNvbD1hZGp1c3Rjb2xvcigid2hpdGUiLCBhbHBoYT0uOCksIHhheHQ9Im4iLCBib3JkZXI9IndoaXRlIiwgbHdkPTQpICNzdGlsbCBuZWVkIHRvIHJlcHJvamVjdCEhIQpMVyA8LSA0CmxpbmVzKHggPSBjKC0xMDAgLCAtMTMwKSwgeSA9IGMoMjAgLCA5MCksIGx0eT0yLCBjb2w9YWRqdXN0Y29sb3IoIndoaXRlIiwgYWxwaGE9MSksIGx3ZD1MVykgI01lc29hbWVyaWNhCmxpbmVzKHggPSBjKC04MCAsIC03MCksIHkgPSBjKDAgLCA5MCksIGx0eT0yLCBjb2w9YWRqdXN0Y29sb3IoIndoaXRlIiwgYWxwaGE9MSksIGx3ZD1MVykgI05XX0xvd2xhbmRfU0EKbGluZXMoeCA9IGMoLTc0ICwgLTUgKSwgeSA9IGMoNSAsIDkwKSwgbHR5PTIsIGNvbD1hZGp1c3Rjb2xvcigid2hpdGUiLCBhbHBoYT0xKSwgbHdkPUxXKSAjTl9Mb3dsYW5kX1NBCmxpbmVzKHggPSBjKDQwICwgMzApLCB5ID0gYygzNiAsIDkwKSwgbHR5PTIsIGNvbD1hZGp1c3Rjb2xvcigid2hpdGUiLCBhbHBoYT0xKSwgbHdkPUxXKSAjRmVydGlsZV9DcmVzYwpsaW5lcyh4ID0gYygxMTAgLCA3MCksIHkgPSBjKDQwICwgOTApLCBsdHk9MiwgY29sPWFkanVzdGNvbG9yKCJ3aGl0ZSIsIGFscGhhPTEpLCBsd2Q9TFcpICNDaGluZXNlX2xvZXNzCmxpbmVzKHggPSBjKDE0MiAsIDE2MCksIHkgPSBjKC01ICwgOTApLCBsdHk9MiwgY29sPWFkanVzdGNvbG9yKCJ3aGl0ZSIsIGFscGhhPTEpLCBsd2Q9TFcpICNOZXdfR3VpbmVhCmxpbmVzKHggPSBjKC04NSAsIC0xMzApLCB5ID0gYygzMyAsIC05MCksIGx0eT0yLCBjb2w9YWRqdXN0Y29sb3IoIndoaXRlIiwgYWxwaGE9MSksIGx3ZD1MVykgI0VfTm9ydGhfQW1lcmkKbGluZXMoeCA9IGMoLTY4ICwgLTc1KSwgeSA9IGMoLTI1ICwgLTkwKSwgbHR5PTIsIGNvbD1hZGp1c3Rjb2xvcigid2hpdGUiLCBhbHBoYT0xKSwgbHdkPUxXKSAjQy9TX0FuZGVzCmxpbmVzKHggPSBjKC0xMCAsIC0yMCksIHkgPSBjKCAxNSwgLTkwKSwgbHR5PTIsIGNvbD1hZGp1c3Rjb2xvcigid2hpdGUiLCBhbHBoYT0xKSwgbHdkPUxXKSAjV19BZnJpY2FuX1NhdgpsaW5lcyh4ID0gYygyNSAsIDQwKSwgeSA9IGMoOSAsIC05MCksIGx0eT0yLCBjb2w9YWRqdXN0Y29sb3IoIndoaXRlIiwgYWxwaGE9MSksIGx3ZD1MVykgI1N1ZGFuaWNfU2F2YW4KbGluZXMoeCA9IGMoODcgLCAxMDApLCB5ID0gYygyMCAsIC05MCksIGx0eT0yLCBjb2w9YWRqdXN0Y29sb3IoIndoaXRlIiwgYWxwaGE9MSksIGx3ZD1MVykgI0dhbmdlc19FX0luZGkKbGluZXMoeCA9IGMoMTIwICwgMTYwKSwgeSA9IGMoMzAgLCAtOTApLCBsdHk9MiwgY29sPWFkanVzdGNvbG9yKCJ3aGl0ZSIsIGFscGhhPTEpLCBsd2Q9TFcpICNMb3dlci1NaWRkbGVZCgoKCmRldi5vZmYoKQpgYGAKCiFbXSg0MDk2Mi5wbmcpCgoKCgojI0ltcG9ydCByYXN0ZXIgZGF0YQpgYGB7cn0KI3N1YnNldCBhbmQgcmVvcmRlciBvcmlnaW5zLiBUaGlzIGlzIGN1cnJlbnRseSBkb25lIGF0IHRoZSBlbmQgb2YgdGhlIHBsb3QgYnV0IHNob3VsZCBiZSBtb3ZlZCBmb3J3YXJkLgoKIyBMb2FkIGRhdGEgZm9yIHBvcHVsYXRpb24gZGVuc2l0eQpsb2FkKCJQb3BEX2FsbF9EZWNlbWJlci5yZGF0YSIpClBvcEQuQUxMCmBgYAoKYGBge3J9CiMgRXh0cmFjdCBkYXRhIHRvIGEgbWF0cml4ClBvcCA8LSB2YWx1ZXMoUG9wRC5BTEwpCnIgPC0gcmFzdGVyKFBvcEQuQUxMLCAxKQpyCmBgYAoKCgoKIyMgR0FNIHNtb290aGluZyBtb2RlbHMKIyMjIyBKdXN0aWZpY2F0aW9uIGZvciBHZW5lcmFsIEFkYXRpdmUgTW9kZWxzLgogIFdlIG5lZWQgdG8ganVzdGlmeSBvdXIgZGVjaXNpb24gdG8gdXNlIGEgR0FNIG92ZXIgb3RoZXIgbW9kZWxzLiBUaGlzIHNob3VsZCBpbmNsdWRlIGNpdGF0aW9ucyB0byBiYWNrIHVwIHRob3NlIGFyZ3VtZW50cy4gCgoKIyMjIEZpdCBhbmQgcGxvdCBHQU0gbW9kZWwgd2l0aCBkaWZmZXJlbnQgZGVncmVlcyBvZiBmcmVlZG9tCldlIHNob3VsZCBtYWtlIG91ciBkZWNpc2lvbnMgdmVyeSB0cmFuc3BhcmVudCBoZXJlLiBXZSBzaG91bGQgYmUgYWJsZSB0byBqdXN0aWZ5IG91ciBkZWNpc2lvbiBvZiAzIGRlZ3JlZXMgb2YgZnJlZWRvbSBvdmVyIG90aGVyIHBvc3NpYmxlIHZhbHVlcy4gCgojIyMjIERlbnNpdHkgcHJvamVjdGlvbnMKCmBgYHtyLCBjYWNoZT1UUlVFfQojIFJlYWQgdGhlIHBvbHlnb25zCmxpYnJhcnkocmdkYWwpCmdldHdkKCkKb3JpZ2lucyA8LSByZWFkU2hhcGVQb2x5KCdPcmlnaW5zX3VwZGF0ZWQuc2hwJykKcHJvajRzdHJpbmcob3JpZ2lucykgCgpgYGAKCgpgYGB7cn0KIyBFeHRyYWN0IGRhdGEKbGlicmFyeShyYXN0ZXIpCmUgPC0gZXh0ZW50KC0xODAsIDE4MCwgLTYwLCA4NCkKYWxsX2NlbGxzIDwtIGV4dHJhY3QociwgZSwgY2VsbG51bWJlciA9IFRSVUUpCgpwZXIub3JpZ2luIDwtIGV4dHJhY3Qociwgb3JpZ2lucywgY2VsbG51bWJlciA9IFRSVUUsIGJ1ZmZlciA9IDEwMDAwMCkKCmxlbmd0aChhbGxfY2VsbHMpCmZvcihpIGluIDE6MjApewphbGxfY2VsbHMgPC0gYWxsX2NlbGxzWy13aGljaChwZXIub3JpZ2luW1tpXV1bLDFdICVpbiUgYWxsX2NlbGxzWywxXSksIF0KfQpsZW5ndGgoYWxsX2NlbGxzKQoKbmFtZXMocGVyLm9yaWdpbikgPC0gb3JpZ2luc0BkYXRhWywgMV0KCnN0cihhbGxfY2VsbHMpCnN0cihwZXIub3JpZ2luKQpgYGAKCmBgYHtyfQpvcmlnaW5fdmVjdG9ycyA8LSByZXAoTkEsIDMpCgpmb3IoaCBpbiAxOjIwKXsKb3JpZ2luSSA8LSBQb3BbcGVyLm9yaWdpbltbaF1dWywgMV0sIF0KY2VsbF92ZWN0b3IgPC0gIGFzLnZlY3RvcihwZXIub3JpZ2luW1toXV1bLCAxXSkKeF92YWx1ZXMgPC0gbWF0cml4KGMoNDoyMSksIGRpbShvcmlnaW5JKVsxXSwgMTgsIGJ5cm93PVRSVUUpCnhfdmFsdWVfdmVjdG9yIDwtIGFzLnZlY3Rvcih4X3ZhbHVlcykKeV92YWx1ZV92ZWN0b3IgPC0gYXMudmVjdG9yKG9yaWdpbkkpCgphbGxfdmVjdG9yc19wcmUgPC0gY2JpbmQocmVwKG5hbWVzKHBlci5vcmlnaW4pW2hdLCBsZW5ndGgoeF92YWx1ZV92ZWN0b3IpKSx4X3ZhbHVlX3ZlY3RvciwgeV92YWx1ZV92ZWN0b3IsIGNlbGxfdmVjdG9yKQpvcmlnaW5fdmVjdG9ycyA8LSByYmluZChvcmlnaW5fdmVjdG9ycywgYWxsX3ZlY3RvcnNfcHJlKQp9CgojbmFtZXMob3JpZ2luX3ZlY3RvcnMpWzFdIDwtICJsb2NhdGlvbiIKb3JpZ2luX3ZlY3RvcnMgPC0gb3JpZ2luX3ZlY3RvcnNbLTEsXQpvcmlnaW5fdmVjdG9ycwpgYGAKCmBgYHtyfQojbm90IGluIG9yaWdpbgoKQWxsIDwtIFBvcFthbGxfY2VsbHNbLCAxXSwgXQpjZWxsX3ZlY3RvciA8LSAgYXMudmVjdG9yKEFsbFssIDFdKQp4X3ZhbHVlcyA8LSBtYXRyaXgoYyg0OjIxKSwgZGltKEFsbClbMV0sIDE4LCBieXJvdz1UUlVFKQp4X3ZhbHVlX3ZlY3RvciA8LSBhcy52ZWN0b3IoeF92YWx1ZXMpCnlfdmFsdWVfdmVjdG9yIDwtIGFzLnZlY3RvcihBbGwpCgphbGxfdmVjdG9yc19wcmUgPC0gY2JpbmQocmVwKCJub3Rfb3JpZ2luIiwgbGVuZ3RoKHhfdmFsdWVfdmVjdG9yKSkseF92YWx1ZV92ZWN0b3IsIHlfdmFsdWVfdmVjdG9yLCBjZWxsX3ZlY3RvcikKYWxsX3ZlY3RvcnMgPC0gYXMuZGF0YS5mcmFtZShyYmluZChvcmlnaW5fdmVjdG9ycywgYWxsX3ZlY3RvcnNfcHJlKSkKbGV2ZWxzKGFsbF92ZWN0b3JzWywxXSkKYGBgCgpgYGB7cn0KCmFsbF92ZWN0b3JzIDwtIGNiaW5kKGFsbF92ZWN0b3JzLCBzY2FsZShhcy5udW1lcmljKGFsbF92ZWN0b3JzWywzXSkpKQpjb2xuYW1lcyhhbGxfdmVjdG9ycykgPC0gYygibG9jYXRpb25fbmFtZSIsICJ4X3ZhbHVlcyIsICJkZW5zaXR5X3ZhbHVlcyIsICJjZWxsX0lEIiwgInNjYWxlZF9kZW5zaXR5X3ZhbHVlcyIpCmFsbF92ZWN0b3JzIDwtIGFsbF92ZWN0b3JzWywgYygxLDIsMyw1LDQpXQphbGxfdmVjdG9ycwpgYGAKCgoKYGBge3IsIGNhY2hlPVRSVUV9CgoKCnBhcihtZnJvdz1jKDQsNiksIG1hcj1jKDAsMCwwLDApLCB4YXh0PSJuIikKZm9yKGggaW4gMToyMCl7CiNoIDwtIDMKZGVuc2l0eV90cmVuZCA8LSBvcmlnaW5fdmVjdG9yc1t3aGljaChvcmlnaW5fdmVjdG9yc1ssMV0gPT0gbmFtZXMocGVyLm9yaWdpbilbaF0pLF0KCnBsb3QoYXMubnVtZXJpYyhkZW5zaXR5X3RyZW5kWywyXSksIGFzLm51bWVyaWMoZGVuc2l0eV90cmVuZFssNF0pLCBjb2w9YWRqdXN0Y29sb3IoImNvcm5mbG93ZXJibHVlIiwgYWxwaGE9MC44KSwgIHhsYWI9InllYXIiLCB5bGFiPSJEZW5zaXR5IiwgeWxpbT1jKC01LDUpLCB4bGltPWMoNCwyMSksIHR5cGU9Im4iKQoKcG9pbnRzKGFzLm51bWVyaWMoZGVuc2l0eV90cmVuZFssMl0pLCBhcy5udW1lcmljKGRlbnNpdHlfdHJlbmRbLDRdKSwgY2V4PTAuNSwgY29sPWFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIDAuNSkpCm10ZXh0KGFzLmNoYXJhY3RlcihkZW5zaXR5X3RyZW5kWzEsMV0pLCAzLCBsaW5lPS0xLCBjZXg9MC41KQp9CgojYWxsIG9yaWdpbnMKcGxvdChhcy5udW1lcmljKGRlbnNpdHlfdHJlbmRbLDJdKSwgYXMubnVtZXJpYyhkZW5zaXR5X3RyZW5kWyw0XSksIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCBhbHBoYT0wLjgpLCAgeGxhYj0ieWVhciIsIHlsYWI9IkRlbnNpdHkiLCB5bGltPWMoLTUsNSksIHhsaW09Yyg0LDIxKSwgdHlwZT0ibiIpCgpwb2ludHMoYXMubnVtZXJpYyhvcmlnaW5fdmVjdG9yc1ssMl0pLCBhcy5udW1lcmljKG9yaWdpbl92ZWN0b3JzWyw0XSksIGNleD0wLjUsIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCAwLjUpKQptdGV4dCgiYWxsIG9yaWdpbnMiLCAzLCBsaW5lPS0xLCBjZXg9MC41KQoKI25vdCBvcmlnaW5zCm5vdF9vcmlnaW5zIDwtIHN1YnNldChhbGxfdmVjdG9ycywgbG9jYXRpb25fbmFtZSA9PSAibm90X29yaWdpbiIpCnBsb3QoYXMubnVtZXJpYyhub3Rfb3JpZ2luc1ssMl0pLCBhcy5udW1lcmljKG5vdF9vcmlnaW5zWyw0XSksIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCBhbHBoYT0wLjgpLCAgeGxhYj0ieWVhciIsIHlsYWI9IkRlbnNpdHkiLCB5bGltPWMoLTUsNSksIHhsaW09Yyg0LDIxKSwgdHlwZT0ibiIpCgpwb2ludHMoYXMubnVtZXJpYyhub3Rfb3JpZ2luc1ssMl0pLCBhcy5udW1lcmljKG5vdF9vcmlnaW5zWyw0XSksIGNleD0wLjUsIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCAwLjUpKQptdGV4dCgiYWxsIG9yaWdpbnMiLCAzLCBsaW5lPS0xLCBjZXg9MC41KQpgYGAKCgoKCgpgYGB7ciwgY2FjaGU9VFJVRX0KCnBhcihtZnJvdz1jKDQsNiksIG1hcj1jKDAsMCwwLDApLCB4YXh0PSJuIikKZm9yKGggaW4gMToyMCl7CiNoIDwtIDMKZGVuc2l0eV90cmVuZCA8LSBhbGxfdmVjdG9yc1t3aGljaChhbGxfdmVjdG9yc1ssMV0gPT0gbmFtZXMocGVyLm9yaWdpbilbaF0pLF0KCnBsb3QoYXMubnVtZXJpYyhkZW5zaXR5X3RyZW5kWywyXSksIGFzLm51bWVyaWMoZGVuc2l0eV90cmVuZFssNF0pLCBjb2w9YWRqdXN0Y29sb3IoImNvcm5mbG93ZXJibHVlIiwgYWxwaGE9MC44KSwgIHhsYWI9InllYXIiLCB5bGFiPSJEZW5zaXR5IiwgeWxpbT1jKC0yLDIpLCB4bGltPWMoNCwyMSksIHR5cGU9Im4iKQoKZm9yKGcgaW4gbGV2ZWxzKGFzLmZhY3RvcihkZW5zaXR5X3RyZW5kWyw1XSkpKXsKc3ViYmVkIDwtIHN1YnNldChkZW5zaXR5X3RyZW5kLCBjZWxsX0lEID09IGcpCm9yZGVyZWRfc3ViYmVkIDwtIHN1YmJlZFtvcmRlcihzdWJiZWQkeF92YWx1ZXMpLCBdCmxpbmVzKGFzLm51bWVyaWMob3JkZXJlZF9zdWJiZWRbLDJdKSwgYXMubnVtZXJpYyhvcmRlcmVkX3N1YmJlZFssNF0pLCBsd2Q9LjMsIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCAwLjgpKQp9Cm10ZXh0KGFzLmNoYXJhY3RlcihkZW5zaXR5X3RyZW5kWzEsMV0pLCAzLCBsaW5lPS0xLCBjZXg9MC41KQp9CgojYWxsIG9yaWdpbnMKcGxvdChhcy5udW1lcmljKGRlbnNpdHlfdHJlbmRbLDJdKSwgYXMubnVtZXJpYyhkZW5zaXR5X3RyZW5kWyw0XSksIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCBhbHBoYT0wLjgpLCAgeGxhYj0ieWVhciIsIHlsYWI9IkRlbnNpdHkiLCB5bGltPWMoLTIsMiksIHhsaW09Yyg0LDIxKSwgdHlwZT0ibiIpCgpmb3IoZyBpbiBsZXZlbHMoYXMuZmFjdG9yKGRlbnNpdHlfdHJlbmRbLDVdKSkpewpzdWJiZWQgPC0gc3Vic2V0KGRlbnNpdHlfdHJlbmQsIGNlbGxfSUQgPT0gZykKb3JkZXJlZF9zdWJiZWQgPC0gc3ViYmVkW29yZGVyKHN1YmJlZCR4X3ZhbHVlcyksIF0KbGluZXMoYXMubnVtZXJpYyhvcmRlcmVkX3N1YmJlZFssMl0pLCBhcy5udW1lcmljKG9yZGVyZWRfc3ViYmVkWyw0XSksIGx3ZD0uMywgY29sPWFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIDAuOCkpCn0KbXRleHQoImFsbCBvcmlnaW5zIiwgMywgbGluZT0tMSwgY2V4PTAuNSkKYGBgCgoKCmBgYHtyLCBjYWNoZT1UUlVFfQpwYXIobWZyb3c9Yyg0LDYpLCBtYXI9YygwLDAsMCwwKSkKZm9yKGggaW4gMToyMCl7CiNoIDwtIDMKZGVuc2l0eV90cmVuZCA8LSBhbGxfdmVjdG9yc1t3aGljaChhbGxfdmVjdG9yc1ssMV0gPT0gbmFtZXMocGVyLm9yaWdpbilbaF0pLF0KCnBsb3QoYXMubnVtZXJpYyhkZW5zaXR5X3RyZW5kWywyXSksIGFzLm51bWVyaWMoZGVuc2l0eV90cmVuZFssNF0pLCBjb2w9YWRqdXN0Y29sb3IoImNvcm5mbG93ZXJibHVlIiwgYWxwaGE9MC44KSwgIHhsYWI9InllYXIiLCB5bGFiPSJEZW5zaXR5IiwgeWxpbT1jKC0zLDMpLCB4bGltPWMoNCwyMSksIHR5cGU9Im4iLCB4YXh0PSJuIiwgeWF4dD0ibiIpCgpwb2ludHMoYXMubnVtZXJpYyhkZW5zaXR5X3RyZW5kWywyXSksIGFzLm51bWVyaWMoZGVuc2l0eV90cmVuZFssNF0pLCBjZXg9MC41LCBjb2w9YWRqdXN0Y29sb3IoImdyZXkiLCAwLjUpKQoKCm9yZGVyZWRfZGVuc2l0eV90cmVuZCA8LSBkZW5zaXR5X3RyZW5kW29yZGVyKGRlbnNpdHlfdHJlbmQkeF92YWx1ZXMpLCBdCgoKZ2FtbWVyIDwtIGxvZXNzKGFzLm51bWVyaWMob3JkZXJlZF9kZW5zaXR5X3RyZW5kWyw0XSkgfiBhcy5udW1lcmljKG9yZGVyZWRfZGVuc2l0eV90cmVuZFssMl0pKQpzdW1tYXJ5KGdhbW1lcikKCgpsaW5lcyhhcy5udW1lcmljKG9yZGVyZWRfZGVuc2l0eV90cmVuZFssMl0pICxwcmVkaWN0KGdhbW1lciksICBjb2w9ImNvcm5mbG93ZXJibHVlIiwgbHdkPTIpCm10ZXh0KGFzLmNoYXJhY3RlcihvcmRlcmVkX2RlbnNpdHlfdHJlbmRbMSwxXSksIDMsIGxpbmU9LTEsIGNleD0wLjUpCn0KCmRlbnNpdHlfdHJlbmQgPC0gYWxsX3ZlY3RvcnNbLTEsXQoKcGxvdChhcy5udW1lcmljKGRlbnNpdHlfdHJlbmRbLDJdKSwgYXMubnVtZXJpYyhkZW5zaXR5X3RyZW5kWyw0XSksIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCBhbHBoYT0wLjgpLCAgeGxhYj0ieWVhciIsIHlsYWI9IkRlbnNpdHkiLCB5bGltPWMoLTMsMyksIHhsaW09Yyg0LDIxKSwgdHlwZT0ibiIsIHhheHQ9Im4iLCB5YXh0PSJuIikKCnBvaW50cyhhcy5udW1lcmljKGRlbnNpdHlfdHJlbmRbLDJdKSwgYXMubnVtZXJpYyhkZW5zaXR5X3RyZW5kWyw0XSksIGNleD0wLjUsIGNvbD1hZGp1c3Rjb2xvcigiZ3JleSIsIDAuNSkpCgoKb3JkZXJlZF9kZW5zaXR5X3RyZW5kIDwtIGRlbnNpdHlfdHJlbmRbb3JkZXIoZGVuc2l0eV90cmVuZCR4X3ZhbHVlcyksIF0KCgpnYW1tZXIgPC0gbG9lc3MoYXMubnVtZXJpYyhvcmRlcmVkX2RlbnNpdHlfdHJlbmRbLDRdKSB+IGFzLm51bWVyaWMob3JkZXJlZF9kZW5zaXR5X3RyZW5kWywyXSkpCnN1bW1hcnkoZ2FtbWVyKQoKCmxlbmd0aChvcmRlcmVkX2RlbnNpdHlfdHJlbmRbLDJdKQpsZW5ndGgocHJlZGljdChnYW1tZXIpKQoKbGluZXMoYXMubnVtZXJpYyhvcmRlcmVkX2RlbnNpdHlfdHJlbmRbLDJdKSAscHJlZGljdChnYW1tZXIpLCAgY29sPSJjb3JuZmxvd2VyYmx1ZSIsIGx3ZD0yKQptdGV4dCgiYWxsIG9yaWdpbnMiLCAzLCBsaW5lPS0xLCBjZXg9MC41KQoKYGBgCgpzcGFuCQp0aGUgcGFyYW1ldGVyIM6xIHdoaWNoIGNvbnRyb2xzIHRoZSBkZWdyZWUgb2Ygc21vb3RoaW5nLgoKVGhlIHNpemUgb2YgdGhlIG5laWdoYm91cmhvb2QgaXMgY29udHJvbGxlZCBieSDOsSAoc2V0IGJ5IHNwYW4gb3IgZW5wLnRhcmdldCkuIEZvciDOsSA8IDEsIHRoZSBuZWlnaGJvdXJob29kIGluY2x1ZGVzIHByb3BvcnRpb24gzrEgb2YgdGhlIHBvaW50cywgYW5kIHRoZXNlIGhhdmUgdHJpY3ViaWMgd2VpZ2h0aW5nIChwcm9wb3J0aW9uYWwgdG8gKDEgLSAoZGlzdC9tYXhkaXN0KV4zKV4zKS4gRm9yIM6xID4gMSwgYWxsIHBvaW50cyBhcmUgdXNlZCwgd2l0aCB0aGUg4oCYbWF4aW11bSBkaXN0YW5jZeKAmSBhc3N1bWVkIHRvIGJlIM6xXigxL3ApIHRpbWVzIHRoZSBhY3R1YWwgbWF4aW11bSBkaXN0YW5jZSBmb3IgcCBleHBsYW5hdG9yeSB2YXJpYWJsZXMuCgpgYGB7ciwgY2FjaGU9VFJVRX0KcGFyKG1mcm93PWMoNCw2KSwgbWFyPWMoMCwwLDAsMCkpCmZvcihoIGluIDE6MjApewojaCA8LSAzCmRlbnNpdHlfdHJlbmQgPC0gYWxsX3ZlY3RvcnNbd2hpY2goYWxsX3ZlY3RvcnNbLDFdID09IG5hbWVzKHBlci5vcmlnaW4pW2hdKSxdCm9yZGVyZWRfZGVuc2l0eV90cmVuZCA8LSBkZW5zaXR5X3RyZW5kW29yZGVyKGRlbnNpdHlfdHJlbmQkeF92YWx1ZXMpLCBdCgpnYW1tZXIgPC0gbG9lc3MoYXMubnVtZXJpYyhvcmRlcmVkX2RlbnNpdHlfdHJlbmRbLDRdKSB+IGFzLm51bWVyaWMob3JkZXJlZF9kZW5zaXR5X3RyZW5kWywyXSksIHNwYW4gPSAuNSkKc3VtbWFyeShnYW1tZXIpCnByZWRpY3RfZ2FtIDwtIHByZWRpY3QoZ2FtbWVyLCBzZT1UUlVFKQoKcGxvdChhcy5udW1lcmljKGRlbnNpdHlfdHJlbmRbLDJdKSwgYXMubnVtZXJpYyhkZW5zaXR5X3RyZW5kWyw0XSksIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCBhbHBoYT0wLjgpLCAgeGxhYj0ieWVhciIsIHlsYWI9IkRlbnNpdHkiLCB5bGltPWMoLTIsMiksIHhsaW09YygwLDIxKSwgdHlwZT0ibiIsIHhheHQ9Im4iLCB5YXh0PSJuIikKI2F4aXMoMSwgbGFiZWw9IHNlcSg0LDIxLCBieT0xKSwgYXQ9cmV2KHNlcSgxLDE4LCBieT0xKSkpCgpwb2x5Z29uKHg9MjItYyhTdGFydF9vZl9lYXJseV93aW5kb3csIFN0YXJ0X29mX2Vhcmx5X3dpbmRvdywgRW5kX29mX2Vhcmx5X3dpbmRvd19zdGFydF9vZl9sYXRlX3dpbmRvdywgRW5kX29mX2Vhcmx5X3dpbmRvd19zdGFydF9vZl9sYXRlX3dpbmRvdyksIHk9YygtMiwgMiwgMiwgLTIpLCBjb2w9YWRqdXN0Y29sb3IoImxpbWVncmVlbiIsIGFscGhhPSAwLjIpLCBib3JkZXI9YWRqdXN0Y29sb3IoImxpbWVncmVlbiIsIGFscGhhPSAwLjkpKQoKcG9seWdvbih4PTIyLWMoIEVuZF9vZl9lYXJseV93aW5kb3dfc3RhcnRfb2ZfbGF0ZV93aW5kb3csIEVuZF9vZl9lYXJseV93aW5kb3dfc3RhcnRfb2ZfbGF0ZV93aW5kb3csIEVuZF9vZl9sYXRlX3dpbmRvdywgRW5kX29mX2xhdGVfd2luZG93KSwgeT1jKC0yLCAyLCAyLCAtMiksIGNvbD1hZGp1c3Rjb2xvcigiZmlyZWJyaWNrIiwgYWxwaGE9IDAuMiksIGJvcmRlcj1hZGp1c3Rjb2xvcigiZmlyZWJyaWNrIiwgYWxwaGE9IDAuOSkpCgphYmxpbmUoaD0wLCBsdHk9MiwgY29sPSJncmV5IikKCmxpbmVzKG9yZGVyZWRfZGVuc2l0eV90cmVuZFssMl0gLHByZWRpY3RfZ2FtJGZpdCwgIGNvbD0iY29ybmZsb3dlcmJsdWUiKQpsaW5lcyhvcmRlcmVkX2RlbnNpdHlfdHJlbmRbLDJdICwgIHByZWRpY3RfZ2FtJGZpdCArIHByZWRpY3RfZ2FtJHNlLmZpdCwgIGNvbD0iZ3JleSIsIGx0eT0xKQpsaW5lcyhvcmRlcmVkX2RlbnNpdHlfdHJlbmRbLDJdICwgIHByZWRpY3RfZ2FtJGZpdCAtIHByZWRpY3RfZ2FtJHNlLmZpdCwgIGNvbD0iZ3JleSIsIGx0eT0xKQoKCm10ZXh0KGFzLmNoYXJhY3RlcihvcmRlcmVkX2RlbnNpdHlfdHJlbmRbMSwxXSksIDMsIGxpbmU9LTEsIGNleD0wLjUpCn0KCmBgYAoKCgoKYGBge3IsIGNhY2hlPVRSVUV9CnBhcihtZnJvdz1jKDIsNSksIG1hcj1jKDAsMCwwLDApKQpmb3IoaiBpbiBzZXEoMC4yLCAyLCBieT0uMikpewoKcGxvdChhcy5udW1lcmljKGRlbnNpdHlfdHJlbmRbLDJdKSwgYXMubnVtZXJpYyhkZW5zaXR5X3RyZW5kWyw0XSksIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCBhbHBoYT0wLjgpLCAgeGxhYj0ieWVhciIsIHlsYWI9IkRlbnNpdHkiLCB5bGltPWMoLTMsMyksIHhsaW09YygwLDIxKSwgdHlwZT0ibiIsIHhheHQ9Im4iKQpheGlzKDEsIGxhYmVsPSBzZXEoNCwyMSwgYnk9MSksIGF0PXJldihzZXEoMSwxOCwgYnk9MSkpKQoKCnBvbHlnb24oeD0yMi1jKFN0YXJ0X29mX2Vhcmx5X3dpbmRvdywgU3RhcnRfb2ZfZWFybHlfd2luZG93LCBFbmRfb2ZfZWFybHlfd2luZG93X3N0YXJ0X29mX2xhdGVfd2luZG93LCBFbmRfb2ZfZWFybHlfd2luZG93X3N0YXJ0X29mX2xhdGVfd2luZG93KSwgeT1jKC0yLCAyLCAyLCAtMiksIGNvbD1hZGp1c3Rjb2xvcigibGltZWdyZWVuIiwgYWxwaGE9IDAuMiksIGJvcmRlcj1hZGp1c3Rjb2xvcigibGltZWdyZWVuIiwgYWxwaGE9IDAuOSkpCgpwb2x5Z29uKHg9MjItYyggRW5kX29mX2Vhcmx5X3dpbmRvd19zdGFydF9vZl9sYXRlX3dpbmRvdywgRW5kX29mX2Vhcmx5X3dpbmRvd19zdGFydF9vZl9sYXRlX3dpbmRvdywgRW5kX29mX2xhdGVfd2luZG93LCBFbmRfb2ZfbGF0ZV93aW5kb3cpLCB5PWMoLTIsIDIsIDIsIC0yKSwgY29sPWFkanVzdGNvbG9yKCJmaXJlYnJpY2siLCBhbHBoYT0gMC4yKSwgYm9yZGVyPWFkanVzdGNvbG9yKCJmaXJlYnJpY2siLCBhbHBoYT0gMC45KSkKCgpmb3IoaCBpbiAxOjE4KXsKI2ggPC0gMwpkZW5zaXR5X3RyZW5kIDwtIGFsbF92ZWN0b3JzW3doaWNoKGFsbF92ZWN0b3JzWywxXSA9PSBsZXZlbHMoYWxsX3ZlY3RvcnNbLDFdKVtoXSksXQpvcmRlcmVkX2RlbnNpdHlfdHJlbmQgPC0gZGVuc2l0eV90cmVuZFtvcmRlcihkZW5zaXR5X3RyZW5kJHhfdmFsdWVzKSwgXQoKZ2FtbWVyIDwtIGxvZXNzKGFzLm51bWVyaWMob3JkZXJlZF9kZW5zaXR5X3RyZW5kWyw0XSkgfiBhcy5udW1lcmljKG9yZGVyZWRfZGVuc2l0eV90cmVuZFssMl0pLCBzcGFuID0gaikKc3VtbWFyeShnYW1tZXIpCnByZWRpY3RfZ2FtIDwtIHByZWRpY3QoZ2FtbWVyLCBzZT1UUlVFKQoKYWJsaW5lKGg9MCwgbHR5PTIsIGNvbD0iZ3JleSIpCgpsaW5lcyhvcmRlcmVkX2RlbnNpdHlfdHJlbmRbLDJdICxwcmVkaWN0X2dhbSRmaXQsICBjb2w9ImNvcm5mbG93ZXJibHVlIikKCn0KbXRleHQocGFzdGUoInNwYW4gPSAiLCBqKSwgMywgbGluZT0tMywgY2V4PTAuNSkKfQpgYGAKCgoKCgoKCgoKCgoKCmBgYHtyLCBjYWNoZT1UUlVFfQojIG5lZWQgdG8gYWRkIGEgZ2xvYmFsIG1lYW4sIGFuIGV2ZXJ5dGhpbmcgYnV0IHRoZSBvcmlnaW5zIG1lYW4sIGFuZCBhIGJ1ZmZlciBhcm91bmQgdGhlIG9yaWdpbnMgbWVhbi4gCiMgRnVuY3Rpb24gc3RhbmRhcmRpemF0aW9uCnN0ZCA8LSBmdW5jdGlvbih4KSB7CiAgYiA8LSAoeCAtIG1pbih4KSkgLyAobWF4KHgpIC0gbWluKHgpKQogIHJldHVybihyZXYoYikpCn0KCgpkaWZmX2RmIDwtIGZ1bmN0aW9uKGgpeyAKIyBDYWxjdWxhdGluZyBtZWFuIGFuZCAKZ2xvYmFsLm1lYW5zIDwtIGdsb2JhbC5TRCA8LSBsaXN0KCkKCmZvciAoaiBpbiAxOmxlbmd0aChwZXIub3JpZ2luKSkgewogICNwcmludChqKQogIG9yaWdpbkkgPC0gUG9wW3Blci5vcmlnaW5bW2pdXVssIDFdLCBdCiAgdGltZSA8LSAyMTo0CiAgb3JpZ2luSSA8LSBuYS5leGNsdWRlKG9yaWdpbkkpCiAgYiA8LSBhcHBseShvcmlnaW5JLCAxLCBzdGQpCiAgbkogPC0gbnJvdyhvcmlnaW5JKQogIHByZWRpY3Rpb25zIDwtIG1hdHJpeChucm93ID0gbkosIG5jb2wgPSBsZW5ndGgodGltZSkpCiAgY29sbmFtZXMocHJlZGljdGlvbnMpIDwtIGFzLmNoYXJhY3Rlcih0aW1lKQogIGZvcihpIGluIDE6bkopIHsKICAgIAogICAgIyBOZWVkIHRvIHNob3cgYSBncmFkaWVudCBvZiB0aGVzZSBkZiB2YWx1ZXMuIAogICAgbW9kZWwgPC0gZ2FtKGJbLCBpXSB+IHModGltZSwgZGYgPSBoKSkKICAgIGNvbCA8LSBzYW1wbGUocmFpbmJvdygxMDApLCAxKQogICAgcHJlZGljdGlvbnNbaSwgXSA8LSBwcmVkaWN0KG1vZGVsKQogICAgI3Bsb3QoYlssIGldIH4gdGltZSkKICAgICNsaW5lcyhwcmVkaWN0aW9uc1tpLCBdIH4gdGltZSkKICB9CiAgZ2xvYmFsLm1lYW5zW1tqXV0gPC0gYXBwbHkocHJlZGljdGlvbnMsIDIsIG1lYW4pIAogIGdsb2JhbC5TRFtbal1dIDwtIGFwcGx5KHByZWRpY3Rpb25zLCAyLCBzZCkKfQoKCm5hbWVzKGdsb2JhbC5tZWFucykgPC0gcGFzdGUobmFtZXMocGVyLm9yaWdpbiksICJNZWFucyIpCm5hbWVzKGdsb2JhbC5TRCkgPC0gcGFzdGUobmFtZXMocGVyLm9yaWdpbiksICJTRCIpCgpyZXR1cm4obGlzdChnbG9iYWwubWVhbnMsIGdsb2JhbC5TRCkpCn0KCgpgYGAKCmBgYHtyfQojIENvbmZpcm0gdGhhdCB0aGUgeC1heGlzIGlzIG9yaWVudGVkIGNvcnJlY3RseQpmb3JfMyA8LSBkaWZmX2RmKDEpCmdsb2JhbC5tZWFucyA8LSBmb3JfM1tbMV1dCmdsb2JhbC5TRCA8LSBmb3JfM1tbMl1dCgppIDwtIDEKcGxvdCg0OjIxLCBnbG9iYWwubWVhbnNbW2ldXSwgY29sPWFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIGFscGhhPTAuOCksICB4bGFiPSJ5ZWFyIiwgeWxhYj0iRGVuc2l0eSIsIHhheHQ9Im4iLCB0eXBlPSJuIiwgeWxpbT1jKDAsMSksIHhsaW09YygwLDIwKSkKCgpwb2x5Z29uKHg9MjItYyhTdGFydF9vZl9lYXJseV93aW5kb3csIFN0YXJ0X29mX2Vhcmx5X3dpbmRvdywgRW5kX29mX2Vhcmx5X3dpbmRvd19zdGFydF9vZl9sYXRlX3dpbmRvdywgRW5kX29mX2Vhcmx5X3dpbmRvd19zdGFydF9vZl9sYXRlX3dpbmRvdykgLCB5PWMoLTEsIDIsIDIsIC0xKSwgY29sPWFkanVzdGNvbG9yKCJsaW1lZ3JlZW4iLCBhbHBoYT0gMC4yKSwgYm9yZGVyPWFkanVzdGNvbG9yKCJsaW1lZ3JlZW4iLCBhbHBoYT0gMC45KSkKCnBvbHlnb24oeD0gMjItYyggRW5kX29mX2Vhcmx5X3dpbmRvd19zdGFydF9vZl9sYXRlX3dpbmRvdywgRW5kX29mX2Vhcmx5X3dpbmRvd19zdGFydF9vZl9sYXRlX3dpbmRvdywgRW5kX29mX2xhdGVfd2luZG93LCBFbmRfb2ZfbGF0ZV93aW5kb3cpICwgeT1jKC0xLCAyLCAyLCAtMSksIGNvbD1hZGp1c3Rjb2xvcigiZmlyZWJyaWNrIiwgYWxwaGE9IDAuMiksIGJvcmRlcj1hZGp1c3Rjb2xvcigiZmlyZWJyaWNrIiwgYWxwaGE9IDAuOSkpCgpvcmlnaW5JIDwtIFBvcFtwZXIub3JpZ2luW1tpXV1bLCAxXSwgXQpmb3IoaiBpbiAxOjE4KXsKcG9pbnRzKDIzLSBjKGppdHRlcihyZXAoNCwgbGVuZ3RoKG9yaWdpbklbLGpdKSksIDQuNSkgICsgaiksIG9yaWdpbklbLGpdLCBwY2g9MTksIGNleD0uMSkKfQoKcG9seWdvbihjKDQ6MjEsMjE6NCkgLTMgLCBjKGdsb2JhbC5tZWFuc1tbaV1dICsgYWJzKGdsb2JhbC5TRFtbaV1dKSwgcmV2KGdsb2JhbC5tZWFuc1tbaV1dIC0gYWJzKGdsb2JhbC5TRFtbaV1dKSkpLCBjb2w9ImNvcm5mbG93ZXJibHVlIikKbGluZXMoZ2xvYmFsLm1lYW5zW1tpXV0sIHR5cGU9ImIiLCBwY2g9bmFtZXMoZ2xvYmFsLm1lYW5zW1tpXV0pKQoKYXhpcygxLCBhdD1zZXEoMSwxOCwgYnk9MSksIGxhYmVsPXJldihzZXEoNCwgMjEsIGJ5PTEpKSkKbXRleHQobmFtZXMoZ2xvYmFsLm1lYW5zKVsxXSwgMywgbGluZT0tMikKCmBgYAoKCmBgYHtyfQptZWFuc19tYXRyaXggPC0gbWF0cml4KHJlcChOQSwxOSoyMCksIDIwLCAxOSkKY29sbmFtZXMobWVhbnNfbWF0cml4KSA8LSBjKCJvcmlnaW4iLCByZXYoc2VxKDQsIDIxLCBieT0xKSkpCm1lYW5zX21hdHJpeFssMV0gPC0gbmFtZXMoZ2xvYmFsLm1lYW5zKQpmb3IoaSBpbiAxOjIwKXsKbWVhbnNfbWF0cml4W2ksMjoxOV0gPC0gZ2xvYmFsLm1lYW5zW1tpXV0KfQpgYGAKCmBgYHtyfQprYWJsZShtZWFuc19tYXRyaXgsIGNhcHRpb249ICJNZWFuIHZhbHVlcyIpCmBgYAoKCmBgYHtyfQojZ2xvYmFsLlNECgpTRF9tYXRyaXggPC0gbWF0cml4KHJlcChOQSwxOSoyMCksIDIwLCAxOSkKY29sbmFtZXMoU0RfbWF0cml4KSA8LSBjKCJvcmlnaW4iLCByZXYoc2VxKDQsIDIxLCBieT0xKSkpClNEX21hdHJpeFssMV0gPC0gbmFtZXMoZ2xvYmFsLlNEKQpmb3IoaSBpbiAxOjIwKXsKU0RfbWF0cml4W2ksMjoxOV0gPC0gZ2xvYmFsLlNEW1tpXV0KfQpgYGAKCmBgYHtyfQprYWJsZShTRF9tYXRyaXgsIGNhcHRpb249ICJTRCB2YWx1ZXMiKQpgYGAKCgpgYGB7cn0KcGFyKG1mcm93PWMoNCw1KSwgbWFyPWMoMCwwLDAsMCkpCgpmb3IoaiBpbiAxOjIwKXsKcGxvdChtZWFuc19tYXRyaXhbMSwyOjE5XSwgY29sPWFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIGFscGhhPTAuOCksIHBjaD1uYW1lcyhtZWFuc19tYXRyaXhbMSwyOjE5XSksIHR5cGU9Im4iLCB4bGFiPSJ5ZWFyIiwgeWxhYj0iRGVuc2l0eSIsIHhheHQ9Im4iLCB5bGltPWMoMCwxKSkKCm9yaWdpbkkgPC0gUG9wW3Blci5vcmlnaW5bW2pdXVssIDFdLCBdCmZvcihoIGluIDE6MTgpewpwb2ludHMoMjMtIGMoaml0dGVyKHJlcCg0LCBsZW5ndGgob3JpZ2luSVssaF0pKSwgNC41KSAgKyBoKSwgb3JpZ2luSVssaF0sIHBjaD0xOSwgY2V4PS4xKQp9CiAgCmxpbmVzKG1lYW5zX21hdHJpeFtqLDI6MTldLCBjb2w9YWRqdXN0Y29sb3IoImNvcm5mbG93ZXJibHVlIiwgYWxwaGE9MC44KSwgcGNoPW5hbWVzKG1lYW5zX21hdHJpeFtqLDI6MTldKSwgdHlwZT0iYiIsIHhsYWI9InllYXIiLCB5bGFiPSJEZW5zaXR5IiwgeGF4dD0ibiIpCn0KCmF4aXMoMSwgYXQ9c2VxKDEsMTgsIGJ5PTEpLCBsYWJlbD1yZXYoc2VxKDQsIDIxLCBieT0xKSkpCgpgYGAKCgoKCmBgYHtyLCBjYWNoZT1UUlVFfQpwYXIobWZyb3c9Yyg0LDUpLCBtYXI9YygwLDAsMCwwKSkKCmZvcl8zIDwtIGRpZmZfZGYoMSkKZ2xvYmFsLm1lYW5zIDwtIGZvcl8zW1sxXV0KZ2xvYmFsLlNEIDwtIGZvcl8zW1syXV0KCmZvcihpIGluIDE6MjApewogIAoKcGxvdCg0OjIxLCBnbG9iYWwubWVhbnNbW2ldXSwgY29sPWFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIGFscGhhPTAuOCksICB4bGFiPSJ5ZWFyIiwgeWxhYj0iRGVuc2l0eSIsIHhheHQ9Im4iLCB0eXBlPSJuIiwgeWxpbT1jKDAsMSksIHhsaW09YygwLDIyKSwgeGF4dD0ibiIsIHlheHQ9Im4iKQoKcG9seWdvbih4PTIyLWMoU3RhcnRfb2ZfZWFybHlfd2luZG93LCBTdGFydF9vZl9lYXJseV93aW5kb3csIEVuZF9vZl9lYXJseV93aW5kb3dfc3RhcnRfb2ZfbGF0ZV93aW5kb3csIEVuZF9vZl9lYXJseV93aW5kb3dfc3RhcnRfb2ZfbGF0ZV93aW5kb3cpICwgeT1jKC0xLCAyLCAyLCAtMSksIGNvbD1hZGp1c3Rjb2xvcigibGltZWdyZWVuIiwgYWxwaGE9IDAuMiksIGJvcmRlcj1hZGp1c3Rjb2xvcigibGltZWdyZWVuIiwgYWxwaGE9IDAuOSkpCgpwb2x5Z29uKHg9IDIyLWMoIEVuZF9vZl9lYXJseV93aW5kb3dfc3RhcnRfb2ZfbGF0ZV93aW5kb3csIEVuZF9vZl9lYXJseV93aW5kb3dfc3RhcnRfb2ZfbGF0ZV93aW5kb3csIEVuZF9vZl9sYXRlX3dpbmRvdywgRW5kX29mX2xhdGVfd2luZG93KSAsIHk9YygtMSwgMiwgMiwgLTEpLCBjb2w9YWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPSAwLjIpLCBib3JkZXI9YWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPSAwLjkpKSAgCiAgCnBvbHlnb24oYyg0OjIxLDIxOjQpIC0zICwgYyhnbG9iYWwubWVhbnNbW2ldXSArIGFicyhnbG9iYWwuU0RbW2ldXSksIHJldihnbG9iYWwubWVhbnNbW2ldXSAtIGFicyhnbG9iYWwuU0RbW2ldXSkpKSwgY29sPSJjb3JuZmxvd2VyYmx1ZSIpCmxpbmVzKGdsb2JhbC5tZWFuc1tbaV1dKQoKI2F4aXMoMSwgYXQ9c2VxKDEsMTgsIGJ5PTEpLCBsYWJlbD1yZXYoc2VxKDQsIDIxLCBieT0xKSkpCm10ZXh0KG5hbWVzKGdsb2JhbC5tZWFucylbaV0sIDMsIGxpbmU9LTEsIGNleD0uNSwgYWRqPS4zKQp9CmBgYApHQU0gbW9kZWwgdXNpbmcgb25lIGRlZ3JlZSBvZiBmcmVlZG9tCgpgYGB7ciwgY2FjaGU9VFJVRX0KcGFyKG1mcm93PWMoNCw1KSwgbWFyPWMoMCwwLDAsMCkpCgpmb3JfMyA8LSBkaWZmX2RmKDIpCmdsb2JhbC5tZWFucyA8LSBmb3JfM1tbMV1dCmdsb2JhbC5TRCA8LSBmb3JfM1tbMl1dCgpmb3IoaSBpbiAxOjIwKXsKcGxvdCg0OjIxLCBnbG9iYWwubWVhbnNbW2ldXSwgY29sPWFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIGFscGhhPTAuOCksICB4bGFiPSJ5ZWFyIiwgeWxhYj0iRGVuc2l0eSIsIHhheHQ9Im4iLCB0eXBlPSJuIiwgeWxpbT1jKDAsMSksIHhsaW09YygwLDIyKSwgeGF4dD0ibiIsIHlheHQ9Im4iKQoKcG9seWdvbih4PTIyLWMoU3RhcnRfb2ZfZWFybHlfd2luZG93LCBTdGFydF9vZl9lYXJseV93aW5kb3csIEVuZF9vZl9lYXJseV93aW5kb3dfc3RhcnRfb2ZfbGF0ZV93aW5kb3csIEVuZF9vZl9lYXJseV93aW5kb3dfc3RhcnRfb2ZfbGF0ZV93aW5kb3cpICwgeT1jKC0xLCAyLCAyLCAtMSksIGNvbD1hZGp1c3Rjb2xvcigibGltZWdyZWVuIiwgYWxwaGE9IDAuMiksIGJvcmRlcj1hZGp1c3Rjb2xvcigibGltZWdyZWVuIiwgYWxwaGE9IDAuOSkpCgpwb2x5Z29uKHg9IDIyLWMoIEVuZF9vZl9lYXJseV93aW5kb3dfc3RhcnRfb2ZfbGF0ZV93aW5kb3csIEVuZF9vZl9lYXJseV93aW5kb3dfc3RhcnRfb2ZfbGF0ZV93aW5kb3csIEVuZF9vZl9sYXRlX3dpbmRvdywgRW5kX29mX2xhdGVfd2luZG93KSAsIHk9YygtMSwgMiwgMiwgLTEpLCBjb2w9YWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPSAwLjIpLCBib3JkZXI9YWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPSAwLjkpKQoKcG9seWdvbihjKDQ6MjEsMjE6NCkgLTMgLCBjKGdsb2JhbC5tZWFuc1tbaV1dICsgYWJzKGdsb2JhbC5TRFtbaV1dKSwgcmV2KGdsb2JhbC5tZWFuc1tbaV1dIC0gYWJzKGdsb2JhbC5TRFtbaV1dKSkpLCBjb2w9ImNvcm5mbG93ZXJibHVlIikKbGluZXMoZ2xvYmFsLm1lYW5zW1tpXV0pCgojYXhpcygxLCBhdD1zZXEoMSwxOCwgYnk9MSksIGxhYmVsPXJldihzZXEoNCwgMjEsIGJ5PTEpKSkKbXRleHQobmFtZXMoZ2xvYmFsLm1lYW5zKVtpXSwgMywgbGluZT0tMSwgY2V4PS41LCBhZGo9LjMpCn0KYGBgCkdBTSBtb2RlbCB1c2luZyB0d28gZGVncmVlIG9mIGZyZWVkb20KCmBgYHtyLCBjYWNoZT1UUlVFfQpwYXIobWZyb3c9Yyg0LDUpLCBtYXI9YygwLDAsMCwwKSkKCmZvcl8zIDwtIGRpZmZfZGYoMykKZ2xvYmFsLm1lYW5zIDwtIGZvcl8zW1sxXV0KZ2xvYmFsLlNEIDwtIGZvcl8zW1syXV0KCmZvcihpIGluIDE6MjApewpwbG90KDQ6MjEsIGdsb2JhbC5tZWFuc1tbaV1dLCBjb2w9YWRqdXN0Y29sb3IoImNvcm5mbG93ZXJibHVlIiwgYWxwaGE9MC44KSwgIHhsYWI9InllYXIiLCB5bGFiPSJEZW5zaXR5IiwgeGF4dD0ibiIsIHR5cGU9Im4iLCB5bGltPWMoMCwxKSwgeGxpbT1jKDAsMjIpLCB4YXh0PSJuIiwgeWF4dD0ibiIpCgpwb2x5Z29uKHg9MjItYyhTdGFydF9vZl9lYXJseV93aW5kb3csIFN0YXJ0X29mX2Vhcmx5X3dpbmRvdywgRW5kX29mX2Vhcmx5X3dpbmRvd19zdGFydF9vZl9sYXRlX3dpbmRvdywgRW5kX29mX2Vhcmx5X3dpbmRvd19zdGFydF9vZl9sYXRlX3dpbmRvdykgLCB5PWMoLTEsIDIsIDIsIC0xKSwgY29sPWFkanVzdGNvbG9yKCJsaW1lZ3JlZW4iLCBhbHBoYT0gMC4yKSwgYm9yZGVyPWFkanVzdGNvbG9yKCJsaW1lZ3JlZW4iLCBhbHBoYT0gMC45KSkKCnBvbHlnb24oeD0gMjItYyggRW5kX29mX2Vhcmx5X3dpbmRvd19zdGFydF9vZl9sYXRlX3dpbmRvdywgRW5kX29mX2Vhcmx5X3dpbmRvd19zdGFydF9vZl9sYXRlX3dpbmRvdywgRW5kX29mX2xhdGVfd2luZG93LCBFbmRfb2ZfbGF0ZV93aW5kb3cpICwgeT1jKC0xLCAyLCAyLCAtMSksIGNvbD1hZGp1c3Rjb2xvcigiZmlyZWJyaWNrIiwgYWxwaGE9IDAuMiksIGJvcmRlcj1hZGp1c3Rjb2xvcigiZmlyZWJyaWNrIiwgYWxwaGE9IDAuOSkpCgpwb2x5Z29uKGMoNDoyMSwyMTo0KSAtMyAsIGMoZ2xvYmFsLm1lYW5zW1tpXV0gKyBhYnMoZ2xvYmFsLlNEW1tpXV0pLCByZXYoZ2xvYmFsLm1lYW5zW1tpXV0gLSBhYnMoZ2xvYmFsLlNEW1tpXV0pKSksIGNvbD0iY29ybmZsb3dlcmJsdWUiKQpsaW5lcyhnbG9iYWwubWVhbnNbW2ldXSkKCiNheGlzKDEsIGF0PXNlcSgxLDE4LCBieT0xKSwgbGFiZWw9cmV2KHNlcSg0LCAyMSwgYnk9MSkpKQptdGV4dChuYW1lcyhnbG9iYWwubWVhbnMpW2ldLCAzLCBsaW5lPS0xLCBjZXg9LjUsIGFkaj0uMykKfQpgYGAKR0FNIG1vZGVsIHVzaW5nIHRocmVlIGRlZ3JlZSBvZiBmcmVlZG9tCgoKCmBgYHtyfQpwYXIobWZyb3c9Yyg0LDUpLCBtYXI9YygwLDAsMCwwKSkKCmZvcl8zIDwtIGRpZmZfZGYoMTcpCmdsb2JhbC5tZWFucyA8LSBmb3JfM1tbMV1dCmdsb2JhbC5TRCA8LSBmb3JfM1tbMl1dCgpmb3IoaSBpbiAxOjIwKXsKcGxvdCg0OjIxLCBnbG9iYWwubWVhbnNbW2ldXSwgY29sPWFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIGFscGhhPTAuOCksICB4bGFiPSJ5ZWFyIiwgeWxhYj0iRGVuc2l0eSIsIHhheHQ9Im4iLCB0eXBlPSJuIiwgeWxpbT1jKDAsMSksIHhsaW09YygwLDIyKSwgeGF4dD0ibiIsIHlheHQ9Im4iKQoKcG9seWdvbih4PTIyLWMoU3RhcnRfb2ZfZWFybHlfd2luZG93LCBTdGFydF9vZl9lYXJseV93aW5kb3csIEVuZF9vZl9lYXJseV93aW5kb3dfc3RhcnRfb2ZfbGF0ZV93aW5kb3csIEVuZF9vZl9lYXJseV93aW5kb3dfc3RhcnRfb2ZfbGF0ZV93aW5kb3cpICwgeT1jKC0xLCAyLCAyLCAtMSksIGNvbD1hZGp1c3Rjb2xvcigibGltZWdyZWVuIiwgYWxwaGE9IDAuMiksIGJvcmRlcj1hZGp1c3Rjb2xvcigibGltZWdyZWVuIiwgYWxwaGE9IDAuOSkpCgpwb2x5Z29uKHg9IDIyLWMoIEVuZF9vZl9lYXJseV93aW5kb3dfc3RhcnRfb2ZfbGF0ZV93aW5kb3csIEVuZF9vZl9lYXJseV93aW5kb3dfc3RhcnRfb2ZfbGF0ZV93aW5kb3csIEVuZF9vZl9sYXRlX3dpbmRvdywgRW5kX29mX2xhdGVfd2luZG93KSAsIHk9YygtMSwgMiwgMiwgLTEpLCBjb2w9YWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPSAwLjIpLCBib3JkZXI9YWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPSAwLjkpKSAgIAogIApwb2x5Z29uKGMoNDoyMSwyMTo0KSAtMyAsIGMoZ2xvYmFsLm1lYW5zW1tpXV0gKyBhYnMoZ2xvYmFsLlNEW1tpXV0pLCByZXYoZ2xvYmFsLm1lYW5zW1tpXV0gLSBhYnMoZ2xvYmFsLlNEW1tpXV0pKSksIGNvbD0iY29ybmZsb3dlcmJsdWUiKQpsaW5lcyhnbG9iYWwubWVhbnNbW2ldXSkKCiNheGlzKDEsIGF0PXNlcSgxLDE4LCBieT0xKSwgbGFiZWw9cmV2KHNlcSg0LCAyMSwgYnk9MSkpKQptdGV4dChuYW1lcyhnbG9iYWwubWVhbnMpW2ldLCAzLCBsaW5lPS0xLCBjZXg9LjUsIGFkaj0uMykKfQpgYGAKR0FNIG1vZGVsIHVzaW5nIDE3IGRlZ3JlZSBvZiBmcmVlZG9tCgoKCiMjIyMgUHJvZHVjdGl2aXR5CmBgYHtyfQojIExvYWQgcGF0cmlja3MgcHJvZHVjdGl2aXR5IFBDQSBkYXRhCmxvYWQoJ1Byb2R1Y3Rpdml0eV9BTEwuUkRBVEEnKQoKIyBMb2FkIG9yaWdpbiBzaGFwZWZpbGVzCm9yaWdpbnMgPC0gcmVhZFNoYXBlUG9seSgnT3JpZ2luc191cGRhdGVkLnNocCcpCgpvcmlnaW4udGltZS5yZWdpb24gPC0gYygyLCAyLCAxLCAxLCAxLCAyLCAyLCAxLCAyLCAyLCAKICAgICAgICAgICAgICAgICAgICAgICAgMiwgMiwgMSwgMiwgMiwgMiwgMiwgMiwgMiwgMikgIyAxID0gZWFybHk7IDIgPSBtaWRkbGUKCgojIEV4dHJhY3QgdGhlIGRhdGEKcHJvZC5vcmlnaW4gPC0gZXh0cmFjdChQcm9kdWN0aXZpdHkuQUxMLCBvcmlnaW5zKQojIE1lYW4gYW5kIFNEIHBlciByZWdpb24KbWVhbnMgPC0gbGFwcGx5KHByb2Qub3JpZ2luLCBjb2xNZWFucywgbmEucm0gPSBUUlVFKQpzZHMgPC0gbGFwcGx5KHByb2Qub3JpZ2luLCBzZCwgbmEucm0gPSBUUlVFKQpuYW1lcyhtZWFucykgPC0gb3JpZ2luc0BkYXRhJENPTlRJTkVOVAp5bWF4IDwtIG1heCh1bmxpc3QobWVhbnMpKQp5bWluIDwtIG1pbih1bmxpc3QobWVhbnMpKQp0aW1lIDwtIDQ6MjEKCiMgUGxvdAojcGRmKCJwcm9kdWN0aXZpdHkucGRmIiwgMjAsIDMwKSAKcGFyKG1mcm93ID0gYyg1LCA0KSwgbWFyID0gYygyLCAyLCAyLCAwKSkKZm9yIChpIGluIDE6bGVuZ3RoKG1lYW5zKSkgewogIHBsb3QoeSA9IG1lYW5zW1tpXV0sIHggPSB0aW1lLCB4bGltID0gYygyMSwgNCksIHlsaW0gPSBjKHltaW4sIHltYXgpLAogICAgICAgbWFpbiA9IG5hbWVzKG1lYW5zKVtpXSwgY2V4Lm1haW4gPSAxLCBjZXgubGFiID0gMSwgY2V4LmF4aXMgPSAxLAogICAgICAgeWxhYiA9ICJQcm9kdWN0aXZpdHkgKFBDQSBheGlzKSIsIHhsYWIgPSAiVGhvdXNhbmQgb2YgeWVhcnMgYWdvIChrKSIsCiAgICAgICBwY2ggPSAyMCwgbHdkID0gMSwgdHlwZSA9ICJsIiwgCiAgICAgICBjb2wgPSBjKCJwdXJwbGUiLCAiZ3JlZW4iKVtvcmlnaW4udGltZS5yZWdpb25baV1dKQogIHVwIDwtIHNkc1tbaV1dICsgbWVhbnNbW2ldXQogIGRvd24gPC0gIG1lYW5zW1tpXV0gLSBzZHNbW2ldXQogIGxpbmVzKHVwIH4gdGltZSwgbHR5ID0gMikKICBsaW5lcyhkb3duIH4gdGltZSwgbHR5ID0gMikKICAKfQojZGV2Lm9mZigpCmBgYAoKCgoKIyNDb21wYXJlIHJhdGVzIGJldHdlZW4gb3JpZ2lucyBhbmQgbm90LW9yaWdpbnMKCiMjQ29tcGFyZSByYXRlcyBiZXR3ZWVuIGRpZmZlcmVudCB0aW1lIHBlcmlvZHMKCgojI1NldHVwIGZpbmFsIGZpZ3VyZQojIyMjIEZyYW1lIGluIHRoZSBsYXlvdXQKYGBge3J9CmEgPC0gbGF5b3V0KG1hdHJpeChjKAoJMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwKCTMsCTYsIDcsIDgsIDksIDEwLCAxMSwJNCwgCgkzLAk1LCA1LCA1LCA1LCA1LCA1LCAJNCwgCgkzLCAJMTIsIDEzLCAxNCwgMTUsIDE2LCAxNywJNCwKCTIsIDIsIDIsIDIsIDIsIDIsIDIsIDIKCSksIDUsIDgsIGJ5cm93PVRSVUUpLCB3aWR0aD1jKDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEpLCBoZWlnaHQ9YygwLjUsIDEsIDEuNSwgMSwgMC41KSkKbGF5b3V0LnNob3coYSkKYGBgCgojIyMjIE1ha2UgYmxhbmsgdGVtcGxhdGUgcGxvdHMKYGBge3J9CmZyYW1lcGxvdCA8LSBmdW5jdGlvbigpewoJcGxvdCgyMTowLHJlcCgwLCAyMiksIHhsaW09YygyMSwwKSwgeWxpbT1jKC0zLCAyLjI1KSwgdHlwZT0ibiIsIHhheHQ9Im4iLCB5YXh0PSJuIiwgeGxhYj0iIiwgeWxhYj0iIikKfQoKZnJhbWVwbG90X2JvdHRvbSA8LSBmdW5jdGlvbigpewoJcGxvdCgyMTowLHJlcCgwLCAyMiksIHhsaW09YygyMSwwKSwgeWxpbT1jKC0zLjI1LCAyKSwgdHlwZT0ibiIsIHhheHQ9Im4iLCB5YXh0PSJuIiwgeGxhYj0iIiwgeWxhYj0iIikKfQpgYGAKCmBgYHtyfQpmcmFtZXBsb3QoKQpmcmFtZXBsb3RfYm90dG9tKCkKYGBgCgoKCgoKIyNUcmVuZCB0aHJvdWdoIHRpbWUgcGFuZWwKCiMjIyMgU2V0dXAgdGhlIHBsb3QgdGVtcGxhdGUgZm9yIHNtYWxsIHBhbmVsIHBsb3RzICgjNi0xNyBvbiBsYXlvdXQgcGFuZWwpCmBgYHtyfQojIyMjIyMjIyMjIyMjIyMjIyMjCgp0eXBlX251bWJlciA8LSA4Cgpjb21wbGV4X2ZpZ3VyZSA8LSBmdW5jdGlvbih0eXBlX251bWJlciwgbG9jYXRpb25fbmFtZSwgaSwgbWVhbnMsIHNkcyl7CgkJCiNwb2x5Z29uKHg9YygtMzAsLTMwLDMwLDMwKSwgeT1jKC0zMCwzMCwzMCwtMzApLCBjb2w9ImJsYWNrIikgIAogIAphYmxpbmUoaD0wLCBsdHk9MikJCQkKCmlmKGkgPCA2KQlwb2x5Z29uKHg9YygxMiwxMiw4LjIsOC4yKSwgeT1jKC0zLDMsMywtMyksIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCBhbHBoYT0wLjIpLCBib3JkZXI9TkEpCQkJCQkKaWYoaSA+IDUpCXBvbHlnb24oeD1jKDguMiw4LjIsNC4yLDQuMiksIHk9YygtMywzLDMsLTMpLCBjb2w9YWRqdXN0Y29sb3IoImNvcm5mbG93ZXJibHVlIiwgYWxwaGE9MC4yKSwgYm9yZGVyPU5BKQoJCQkKICAKICAJbWF0Y2ggPC0gZG9tZXN0aWNhdGlvbl90aW1lc1sgd2hpY2goZG9tZXN0aWNhdGlvbl90aW1lcyRSZWdpb24gPT0gbGV2ZWxzKGRvbWVzdGljYXRpb25fdGltZXMkUmVnaW9uKVsgdHlwZV9udW1iZXJdKSwgOV0KCW1heGVyIDwtIG1heChtYXRjaCwgbmEucm09VFJVRSkKCWJyZWFrX29uZV8xIDwtIG1heGVyCgkJCWJyZWFrX3R3b18xIDwtIG1heGVyIC0gcXVhbnRpbGUoailbMl0KCQkJCQojCXBvbHlnb24oeD1jKGJyZWFrX3R3b18xLCBicmVha190d29fMSwgYnJlYWtfb25lXzEsIGJyZWFrX29uZV8xKSwgeT1jKDAsIDEsIDEsIDApLCBjb2w9YWRqdXN0Y29sb3IoImNvcm5mbG93ZXJibHVlIiwgYWxwaGE9MC41KSwgYm9yZGVyPU5BKQoJCWxpbmVzKHg9YyhicmVha19vbmVfMSwgYnJlYWtfb25lXzEpLCB5PWMoLTMsMyksIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCBhbHBoYT0wLjcpLCBsd2Q9MykJCgogIAogIAogIG1hdGNoIDwtIGRvbWVzdGljYXRpb25fdGltZXNbIHdoaWNoKGRvbWVzdGljYXRpb25fdGltZXMkUmVnaW9uID09IGxldmVscyhkb21lc3RpY2F0aW9uX3RpbWVzJFJlZ2lvbilbIHR5cGVfbnVtYmVyXSksIDEwXQoJbWF4ZXIgPC0gbWF4KG1hdGNoLCBuYS5ybT1UUlVFKQoJYnJlYWtfb25lXzIgPC0gbWF4ZXIKCQkJYnJlYWtfdHdvXzIgPC0gbWF4ZXIgLSBxdWFudGlsZShqKVsyXQoJCQkJCiMJcG9seWdvbih4PWMoYnJlYWtfdHdvXzIsIGJyZWFrX3R3b18yLCBicmVha19vbmVfMiwgYnJlYWtfb25lXzIpLCB5PWMoMSwgMiwgMiwgMSksIGNvbD1hZGp1c3Rjb2xvcigibGltZWdyZWVuIiwgYWxwaGE9MC41KSwgYm9yZGVyPU5BKQoJCWxpbmVzKHg9YyhicmVha19vbmVfMiwgYnJlYWtfb25lXzIpLCB5PWMoLTMsMyksIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCBhbHBoYT0xKSwgbHdkPTMpCQoJCgkJCiAgCQkJCQkJCgltYXRjaCA8LSBkb21lc3RpY2F0aW9uX3RpbWVzWyB3aGljaChkb21lc3RpY2F0aW9uX3RpbWVzJFJlZ2lvbiA9PSBsZXZlbHMoZG9tZXN0aWNhdGlvbl90aW1lcyRSZWdpb24pWyB0eXBlX251bWJlcl0pLCA5XQoJbWF4ZXIgPC0gbWF4KG1hdGNoLCBuYS5ybT1UUlVFKQoJaiA8LSBlY2RmKG1heGVyLW1hdGNoKQoJcHJpbnQoaikKCQoKeF9zZXEgPC0gcmV2KGMoMCxzZXEoMCwgbWF4ZXIsIGxlbmd0aC5vdXQ9MTAwKSkpCnlfc2VxIDwtIGMoMCwgaihzZXEoMCwgbWF4ZXIsIGxlbmd0aC5vdXQ9MTAwKSkpIAoKI2xpbmVzKHhfc2VxLCB5X3NlcSwgdHlwZT0ibCIsIHlsaW09YygtMSwxKSkKcG9seWdvbihjKDAsIHhfc2VxKSwgYygwLCB5X3NlcSkgLTMsIGJvcmRlcj1OQSwgY29sPWFkanVzdGNvbG9yKCJ3aGl0ZSIsIGFscGhhPTEpLCBsd2Q9LjUpCnBvbHlnb24oYygwLCB4X3NlcSksIGMoMCwgeV9zZXEpIC0zLCBib3JkZXI9ImNvcm5mbG93ZXJibHVlIiwgY29sPWFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIGFscGhhPS41KSwgbHdkPS41KQojYWJsaW5lKHY9IG1heGVyIC0gcXVhbnRpbGUoailbMl0pCgoKCW1hdGNoIDwtIGRvbWVzdGljYXRpb25fdGltZXNbIHdoaWNoKGRvbWVzdGljYXRpb25fdGltZXMkUmVnaW9uID09IGxldmVscyhkb21lc3RpY2F0aW9uX3RpbWVzJFJlZ2lvbilbIHR5cGVfbnVtYmVyXSksIDEwXQoJbWF4ZXIgPC0gbWF4KG1hdGNoLCBuYS5ybT1UUlVFKQoJaiA8LSBlY2RmKG1heGVyLW1hdGNoKQoJcHJpbnQoaikKCQoKeF9zZXEgPC0gcmV2KGMoMCxzZXEoMCwgbWF4ZXIsIGxlbmd0aC5vdXQ9MTAwKSkpCnlfc2VxIDwtIGMoMCwgaihzZXEoMCwgbWF4ZXIsIGxlbmd0aC5vdXQ9MTAwKSkpIAoKI2xpbmVzKHhfc2VxLCB5X3NlcSkKcG9seWdvbihjKDAsIHhfc2VxKSwgYygwLCB5X3NlcSkgLTMsIGJvcmRlcj0id2hpdGUiLCBjb2w9YWRqdXN0Y29sb3IoIndoaXRlIiwgYWxwaGE9MSksIGx3ZD0uNSkKcG9seWdvbihjKDAsIHhfc2VxKSwgYygwLCB5X3NlcSkgLTMsIGJvcmRlcj0id2hpdGUiLCBjb2w9YWRqdXN0Y29sb3IoImNvcm5mbG93ZXJibHVlIiwgYWxwaGE9MSksIGx3ZD0uNSkKCgoJCgkJCgoJCQoJCQoJCSNhYmxpbmUodj0xMSkKCXR5cGUgPC0gMwoJCQoJCWlmKHR5cGUgPT0gMSl7Cgl4IDwtIGMobWVhbnNbW2ldXSAsIG1lYW5zW1tpXV0gICsgYWJzKHNkc1tbaV1dKSwgbWVhbnNbW2ldXSAgLSBhYnMoc2RzW1tpXV0pKQoJc2NhbGVkIDwtIHNjYWxlKHggLCBjZW50ZXI9VFJVRSkKCW1lYW5zcyA8LSBzY2FsZWRbMToxOF0KCXNkc3NfcGx1cyA8LSBzY2FsZWRbMTk6MzZdCglzZHNzX21pbnVzIDwtIHNjYWxlZFszNzo1NF0KCSNhYmxpbmUodj0xMCwgY29sPSJyZWQiKQoJbGVuZ3RoKHNjYWxlZCkKCSNsaW5lcyg0OjIxLCBtZWFuc1tbaV1dICsgc2RzW1tpXV0pCgkjcG9seWdvbih4PWMoNDoyMSwgMjE6NCksIHk9YyhzZHNzX3BsdXMsIHJldihzZHNzX21pbnVzKSksIGNvbD1hZGp1c3Rjb2xvcigiZmlyZWJyaWNrIiwgYWxwaGE9MSksIGJvcmRlcj0id2hpdGUiKQoJcG9seWdvbih4PWMoMjE6NCw0OjIxKSwgeT1jKHNkc3NfcGx1cywgcmV2KHNkc3NfbWludXMpKSwgY29sPWFkanVzdGNvbG9yKCJmaXJlYnJpY2siLCBhbHBoYT0xKSwgYm9yZGVyPSJ3aGl0ZSIpCQoJfQoJCglpZih0eXBlID09IDIpewojaCA8LSAzCmRlbnNpdHlfdHJlbmQgPC0gYWxsX3ZlY3RvcnNbd2hpY2goYWxsX3ZlY3RvcnNbLDFdID09IGxvY2F0aW9uX25hbWUgKSxdCgojcGxvdChhcy5udW1lcmljKGRlbnNpdHlfdHJlbmRbLDJdKSwgYXMubnVtZXJpYyhkZW5zaXR5X3RyZW5kWyw0XSksIGNvbD1hZGp1c3Rjb2xvcigiY29ybmZsb3dlcmJsdWUiLCBhbHBoYT0wLjgpLCAgeGxhYj0ieWVhciIsIHlsYWI9IkRlbnNpdHkiLCB5bGltPWMoLTIsMiksIHhsaW09Yyg0LDIxKSwgdHlwZT0ibiIpCgpmb3IoZyBpbiBsZXZlbHMoYXMuZmFjdG9yKGRlbnNpdHlfdHJlbmRbLDVdKSkpewpzdWJiZWQgPC0gc3Vic2V0KGRlbnNpdHlfdHJlbmQsIGNlbGxfSUQgPT0gZykKb3JkZXJlZF9zdWJiZWQgPC0gc3ViYmVkW29yZGVyKHN1YmJlZCR4X3ZhbHVlcyksIF0KbGluZXMoMjItYXMubnVtZXJpYyhvcmRlcmVkX3N1YmJlZFssMl0pLCBhcy5udW1lcmljKG9yZGVyZWRfc3ViYmVkWyw0XSksIGx3ZD0uMywgY29sPWFkanVzdGNvbG9yKCJsaW1lZ3JlZW4iLCAwLjMpKQp9CgoKZGVuc2l0eV90cmVuZCA8LSBhbGxfdmVjdG9yc1t3aGljaChhbGxfdmVjdG9yc1ssMV0gPT0gbG9jYXRpb25fbmFtZSksXQpvcmRlcmVkX2RlbnNpdHlfdHJlbmQgPC0gZGVuc2l0eV90cmVuZFtvcmRlcihkZW5zaXR5X3RyZW5kJHhfdmFsdWVzKSwgXQoKI2dhbW1lciA8LSBsb2Vzcyhhcy5udW1lcmljKG9yZGVyZWRfZGVuc2l0eV90cmVuZFssNF0pIH4gYXMubnVtZXJpYyhvcmRlcmVkX2RlbnNpdHlfdHJlbmRbLDJdKSwgc3BhbiA9IDEpCmdhbW1lciA8LSBnYW0oYXMubnVtZXJpYyhvcmRlcmVkX2RlbnNpdHlfdHJlbmRbLDRdKSB+IHMoYXMubnVtZXJpYyhvcmRlcmVkX2RlbnNpdHlfdHJlbmRbLDJdKSwgZGYgPSAzKSkKCnN1bW1hcnkoZ2FtbWVyKQpwcmVkaWN0X2dhbSA8LSBwcmVkaWN0KGdhbW1lciwgc2U9VFJVRSkKCgoKYWJsaW5lKGg9MCwgbHR5PTIsIGNvbD0iZ3JleSIpCgoKI2xpbmVzKHJldihvcmRlcmVkX2RlbnNpdHlfdHJlbmRbLDJdKSAsICBwcmVkaWN0X2dhbSRmaXQgKyBwcmVkaWN0X2dhbSRzZS5maXQsICBjb2w9Im9yYW5nZSIsIGx0eT0xLCBsd2Q9MSkKI2xpbmVzKHJldihvcmRlcmVkX2RlbnNpdHlfdHJlbmRbLDJdKSAsICBwcmVkaWN0X2dhbSRmaXQgLSBwcmVkaWN0X2dhbSRzZS5maXQsICBjb2w9Im9yYW5nZSIsIGx0eT0xLCBsd2Q9MSkKcG9seWdvbih4PTMrYyhyZXYob3JkZXJlZF9kZW5zaXR5X3RyZW5kWywyXSksIG9yZGVyZWRfZGVuc2l0eV90cmVuZFssMl0gKSwgeT1jKHByZWRpY3RfZ2FtJGZpdCwgcmV2KHByZWRpY3RfZ2FtJGZpdCkpLCBjb2w9YWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPS41KSxidHk9Im4iLCBsd2Q9LjIpCmxpbmVzKDMrcmV2KGFzLm51bWVyaWMob3JkZXJlZF9kZW5zaXR5X3RyZW5kWywyXSkpICxwcmVkaWN0X2dhbSRmaXQsICBjb2w9ImZpcmVicmljayIsIGx3ZD0xKQoKCgl9CgppZih0eXBlID09IDMpewoJCiNoIDwtIDMKZGVuc2l0eV90cmVuZCA8LSBhbGxfdmVjdG9yc1t3aGljaChhbGxfdmVjdG9yc1ssMV0gPT0gbG9jYXRpb25fbmFtZSApLF0KCiNwbG90KGFzLm51bWVyaWMoZGVuc2l0eV90cmVuZFssMl0pLCBhcy5udW1lcmljKGRlbnNpdHlfdHJlbmRbLDRdKSwgY29sPWFkanVzdGNvbG9yKCJjb3JuZmxvd2VyYmx1ZSIsIGFscGhhPTAuOCksICB4bGFiPSJ5ZWFyIiwgeWxhYj0iRGVuc2l0eSIsIHlsaW09YygtMiwyKSwgeGxpbT1jKDQsMjEpLCB0eXBlPSJuIikKCmZvcihnIGluIGxldmVscyhhcy5mYWN0b3IoZGVuc2l0eV90cmVuZFssNV0pKSl7CnN1YmJlZCA8LSBzdWJzZXQoZGVuc2l0eV90cmVuZCwgY2VsbF9JRCA9PSBnKQpvcmRlcmVkX3N1YmJlZCA8LSBzdWJiZWRbb3JkZXIoc3ViYmVkJHhfdmFsdWVzKSwgXQpsaW5lcygzK3Jldihhcy5udW1lcmljKG9yZGVyZWRfc3ViYmVkWywyXSkpLCBhcy5udW1lcmljKG9yZGVyZWRfc3ViYmVkWyw0XSksIGx3ZD0uMywgY29sPWFkanVzdGNvbG9yKCJsaW1lZ3JlZW4iLCAwLjMpKQp9CgoKZGVuc2l0eV90cmVuZCA8LSBhbGxfdmVjdG9yc1t3aGljaChhbGxfdmVjdG9yc1ssMV0gPT0gbG9jYXRpb25fbmFtZSksXQpvcmRlcmVkX2RlbnNpdHlfdHJlbmQgPC0gZGVuc2l0eV90cmVuZFtvcmRlcihkZW5zaXR5X3RyZW5kJHhfdmFsdWVzKSwgXQoKZ2FtbWVyIDwtIGxvZXNzKGFzLm51bWVyaWMob3JkZXJlZF9kZW5zaXR5X3RyZW5kWyw0XSkgfiBhcy5udW1lcmljKG9yZGVyZWRfZGVuc2l0eV90cmVuZFssMl0pLCBzcGFuID0gMSkKc3VtbWFyeShnYW1tZXIpCnByZWRpY3RfZ2FtIDwtIHByZWRpY3QoZ2FtbWVyLCBzZT1UUlVFKQoKCgphYmxpbmUoaD0wLCBsdHk9MiwgY29sPSJncmV5IikKCgojbGluZXMocmV2KG9yZGVyZWRfZGVuc2l0eV90cmVuZFssMl0pICwgIHByZWRpY3RfZ2FtJGZpdCArIHByZWRpY3RfZ2FtJHNlLmZpdCwgIGNvbD0ib3JhbmdlIiwgbHR5PTEsIGx3ZD0xKQojbGluZXMocmV2KG9yZGVyZWRfZGVuc2l0eV90cmVuZFssMl0pICwgIHByZWRpY3RfZ2FtJGZpdCAtIHByZWRpY3RfZ2FtJHNlLmZpdCwgIGNvbD0ib3JhbmdlIiwgbHR5PTEsIGx3ZD0xKQoKcG9seWdvbih4PTMrYyhyZXYob3JkZXJlZF9kZW5zaXR5X3RyZW5kWywyXSksIG9yZGVyZWRfZGVuc2l0eV90cmVuZFssMl0gKSwgeT1jKHByZWRpY3RfZ2FtJGZpdCwgcmV2KHByZWRpY3RfZ2FtJGZpdCkpLCBjb2w9YWRqdXN0Y29sb3IoImZpcmVicmljayIsIGFscGhhPS41KSxidHk9Im4iLCBsd2Q9LjIpCmxpbmVzKDMrcmV2KGFzLm51bWVyaWMob3JkZXJlZF9kZW5zaXR5X3RyZW5kWywyXSkpICxwcmVkaWN0X2dhbSRmaXQsICBjb2w9ImZpcmVicmljayIsIGx3ZD0xKQoKCgoJfQoKCQoJCiNtZWFuc19sb25nX3kgPC0gYygxLDEsMSwxLDEsIG1lYW5zcykKI21lYW5zX2xvbmdfeCA8LSBjKDA6NCwgNDoyMSkKIAoJCSMJYnJlYWtfb25lIDwtIGJyZWFrX29uZV8yCgkJIwlicmVha190d28gPC0gYnJlYWtfdHdvXzIKCQkjCQlwb2x5Z29uKHg9YyhicmVha19vbmUsIGJyZWFrX29uZSwgMjIsIDIyKSwgeT1jKDEsIDIsIDIsIDEpLCBjb2w9YWRqdXN0Y29sb3IoIndoaXRlIiwgYWxwaGE9MC44KSwgYm9yZGVyPU5BKQoJCSMJCXBvbHlnb24oeD1jKGJyZWFrX3R3bywgYnJlYWtfdHdvLCBicmVha19vbmUsIGJyZWFrX29uZSksIHk9YygxLCAyLCAyLCAxKSwgY29sPWFkanVzdGNvbG9yKCJ3aGl0ZSIsIGFscGhhPTApLCBib3JkZXI9TkEpCgkJCSMJcG9seWdvbih4PWMoLTEsLTEsIGJyZWFrX3R3byAsIGJyZWFrX3R3byksIHk9YygxLjksIDMuMSwgMy4xLCAxLjkpLCBjb2w9YWRqdXN0Y29sb3IoIndoaXRlIiwgYWxwaGE9MC44KSwgYm9yZGVyPU5BKQkKCQkJCSNhYmxpbmUodj0gYnJlYWtfb25lLCBjb2w9IndoaXRlIikKCQkJCSNhYmxpbmUodj0gYnJlYWtfdHdvLCBjb2w9IndoaXRlIikKCQkJCQoJCQkjCWJyZWFrX29uZSA8LSBicmVha19vbmVfMQoJCSMJYnJlYWtfdHdvIDwtIGJyZWFrX3R3b18xCgkJIwkJcG9seWdvbih4PWMoYnJlYWtfb25lLCBicmVha19vbmUsIDIyLCAyMiksIHk9YygwLCAxLCAxLCAwKSwgY29sPWFkanVzdGNvbG9yKCJ3aGl0ZSIsIGFscGhhPTAuOCksIGJvcmRlcj1OQSkKCQkjCQlwb2x5Z29uKHg9YyhicmVha190d28sIGJyZWFrX3R3bywgYnJlYWtfb25lLCBicmVha19vbmUpLCB5PWMoMCwgMSwgMSwgMCksIGNvbD1hZGp1c3Rjb2xvcigid2hpdGUiLCBhbHBoYT0wKSwgYm9yZGVyPU5BKQoJCQkjCXBvbHlnb24oeD1jKC0xLC0xLCBicmVha190d28gLCBicmVha190d28pLCB5PWMoLTEuMSwgLjEsIC4xLCAtMS4xKSwgY29sPWFkanVzdGNvbG9yKCJ3aGl0ZSIsIGFscGhhPTAuOCksIGJvcmRlcj1OQSkJCgkJCQkjYWJsaW5lKHY9IGJyZWFrX29uZSwgY29sPSJ3aGl0ZSIpCgkJCQkjYWJsaW5lKHY9IGJyZWFrX3R3bywgY29sPSJ3aGl0ZSIpCgkJCQkKI2xpbmVzKHg9YyhicmVha19vbmVfMiwgYnJlYWtfb25lXzIpLCB5PWMoMSwzKSwgY29sPSJ3aGl0ZSIpCiNsaW5lcyh4PWMoYnJlYWtfb25lXzEsIGJyZWFrX29uZV8xKSwgeT1jKDEsLTEpLCBjb2w9IndoaXRlIikKI2xpbmVzKHg9YyhicmVha190d29fMiwgYnJlYWtfdHdvXzIpLCB5PWMoMSwzKSwgY29sPSJ3aGl0ZSIpCiNsaW5lcyh4PWMoYnJlYWtfdHdvXzEsIGJyZWFrX3R3b18xKSwgeT1jKDEsLTEpLCBjb2w9IndoaXRlIikgCiNsaW5lcyg0OjIxLCBtZWFuc3MpCgkjbGluZXMoMjE6NCwgbWVhbnNzKQoJCn0KCgpgYGAKCmBgYHtyfQpmcmFtZXBsb3QoKQpjb21wbGV4X2ZpZ3VyZSgxLG5hbWVzKHBlci5vcmlnaW4pWzJdLCAxLCBnbG9iYWwubWVhbnMsIGdsb2JhbC5TRCkgCgpheGlzKDEpCmF4aXMoMikKYGBgCgoKIyNBc3NlbWJsZSB0aGUgZmlndXJlCiMjIyMgQXNzZW1ibGUgdGhlIGZpZ3VyZQpgYGB7cn0KcXVhcnR6KHdpZHRoPTgsIGhlaWdodD04KQoKbGF5b3V0KG1hdHJpeChjKAoJMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwKCTMsCTYsIDcsIDgsIDksIDEwLCAxMSwJNCwgCgkzLAk1LCA1LCA1LCA1LCA1LCA1LCAJNCwgCgkzLCAJMTIsIDEzLCAxNCwgMTUsIDE2LCAxNywJNCwKCTIsIDIsIDIsIDIsIDIsIDIsIDIsIDIKCSksIDUsIDgsIGJ5cm93PVRSVUUpLCB3aWR0aD1jKDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEpLCBoZWlnaHQ9YygwLjcsIDEsIDEuNSwgMSwgMC43KSkKCgpwYXIobWFyPWMoMCwwLDAsMCkpCgojIDEtNCBsYWJlbCBtYXJnaW5zCmJsYW5rcGxvdCA8LSBmdW5jdGlvbigpewoJCglwbG90KDAsMCwgeGxpbT1jKDQsMjEpLCB5bGltPWMoMSwgMS4yNSksIGJ0eT0ibiIsIHR5cGU9Im4iLCB4YXh0PSJuIiwgeWF4dD0ibiIsIHhsYWI9IiIsIHlsYWI9IiIpCn0KCmJsYW5rcGxvdCgpCmJsYW5rcGxvdCgpCmJsYW5rcGxvdCgpCmJsYW5rcGxvdCgpCgoKCgoKCgpkIDwtIHJlYWRQTkcoIjQwOTYyLnBuZyIpCmRpbShkKQpwYXIobWFyPWMoMCwwLDAsMCkpCnBsb3QoMDozNjAsMDozNjAsdHlwZT0ibiIseGxpbT1jKDIwLDM2MCkseWxpbT1jKDY1LDI5NSksIHlheHQ9Im4iLCB4YXh0PSJuIikKcmFzdGVySW1hZ2UoZCwgLTI4LjUsIC0xMy41LCAzODgsIDM3NSwgaW50ZXJwb2xhdGU9VFJVRSwgY29sPWQpCmF4aXMoMiwgbGFiZWw9c2VxKC05MCwgOTAsIGxlbmd0aC5vdXQgPSAxOSksIGF0PXNlcSgxLCAzNjAsIGxlbmd0aC5vdXQgPSAxOSksIGxhcz0xKQptdGV4dCgibGF0aXR1ZGUiLCAyLCBsaW5lPTQsIGF0PTE4MCkKYWJsaW5lKGg9c2VxKDEsIDM2MCwgbGVuZ3RoLm91dCA9IDE5KSwgY29sPWFkanVzdGNvbG9yKCJncmV5MTAiLCBhbHBoYT0gMC40KSwgbHdkPTEpCmFibGluZShoPTE4MCwgY29sPWFkanVzdGNvbG9yKCJ3aGl0ZSIsIGFscGhhPSAuNSksIGx3ZD0xKQoKCmxvYWQoJ1BvcERfYWxsX0RlY2VtYmVyLnJkYXRhJykKCiMgRXh0cmFjdCB0aGUgZGF0YQpwcm9kLm9yaWdpbiA8LSBleHRyYWN0KFBvcEQuQUxMLCBvcmlnaW5zX3N1YnNldCkKCmxpYnJhcnkobWF0cml4U3RhdHMpCiMgTWVhbiBhbmQgU0QgcGVyIHJlZ2lvbgptZWFucyA8LSBsYXBwbHkocHJvZC5vcmlnaW4sIGNvbE1lYW5zLCBuYS5ybSA9IFRSVUUpCnNkcyA8LSBsYXBwbHkocHJvZC5vcmlnaW4sIGNvbFNkcywgbmEucm0gPSBUUlVFKQoKIyMgbmV3IHZhbHVlcyBmcm9tIEJydW5vJ3MgR0FNIG1vZGVsIChwcm9kdWNlZCBpbiBzY3JpcHQgY2FsbGVkIFBvcHVsYXRpb25fVHJlbmRfcGVyX3kuUikKZm9yXzMgPC0gZGlmZl9kZigzKQpnbG9iYWwubWVhbnMgPC0gZm9yXzNbWzFdXQpnbG9iYWwuU0QgPC0gZm9yXzNbWzJdXQoKbWVhbnMgPC0gZ2xvYmFsLm1lYW5zCnNkcyA8LSBnbG9iYWwuZ2FtcwoKbmFtZXMobWVhbnMpIDwtIG9yaWdpbnNfc3Vic2V0QGRhdGEkQ09OVElORU5UCnltYXggPC0gbWF4KHVubGlzdChtZWFucykpCnltaW4gPC0gbWluKHVubGlzdChtZWFucykpCnRpbWUgPC0gNDoyMQojcGxvdChvcmlnaW5zKQojbWVhbnNbWzFdXSArCiNzZHNbWzFdXQojc2NhbGUoYXMubnVtZXJpYyhtZWFuc1tbMV1dKSwgY2VudGVyPUZBTFNFKQoKbmFtZV92ZWN0b3IgPC0gYXMuY2hhcmFjdGVyKG9yaWdpbnNfc3Vic2V0QGRhdGEkQ09OVElORU5UKQoKCgpmb3IoaSBpbiAxOjEyKXsKCgkKCglpZihpID4gNil7ZnJhbWVwbG90KCl9ZWxzZXtmcmFtZXBsb3RfYm90dG9tKCl9CgoJCgkJIyMgY3VzdG9taXplIHBvbHlnb25zIGZvciBlYWNoIGdyYXBoCglpZihpID09IDEpeyAjbWVzb2FtZXJpY2EgICN2YWx1ZXMgZnJvbSBMYXJzb24KCQkKCQkJY29tcGxleF9maWd1cmUoMywgIk1lc29hbWVyaWNhIiwgaSwgbWVhbnMsIHNkcykKCQkJCQoJCgkJfQoJCgkKCSMjIyMjIyMjIwoJaWYoaSA9PSAyICl7ICNOVyBsb3dsYW5kcyBTQSAgI3ZhbHVlcyBmcm9tIExhcnNvbgoJCQoJCWNvbXBsZXhfZmlndXJlKDYsICJOV19Mb3dsYW5kX1NBIiwgaSwgbWVhbnMsIHNkcykKCQoKCQl9CgkJCgkJIyMjIyMjIyMjCglpZiggaSA9PSAzKXsgI05XIGxvd2xhbmRzIFNBICAjdmFsdWVzIGZyb20gTGFyc29uCgkJCgkJY29tcGxleF9maWd1cmUoNiwgIk5fTG93bGFuZF9TQSIsIGksIG1lYW5zLCBzZHMpCgkJCgkJfQoKCgkJIyMjIyMjIyMjCglpZihpID09IDQpeyAjRmVydGlsZSBjcmVzY2VudCBha2EgU291dGh3ZXN0IGFzaWEgICN2YWx1ZXMgZnJvbSBMYXJzb24KCQkKCQkKCWNvbXBsZXhfZmlndXJlKDgsICJGZXJ0aWxlX0NyZXNjIiwgaSwgbWVhbnMsIHNkcykKCQkJCQoJCX0KCQkKCQkjIyMjIyMjIyMKCWlmKGkgPT0gNSl7ICNsb2VzcyBwbGF0ZWF1ICAjdmFsdWVzIGZyb20gTGFyc29uCgkJCgkJY29tcGxleF9maWd1cmUoMiwgIkNoaW5lc2VfbG9lc3MiLCBpLCBtZWFucywgc2RzKQoJCQkKCQl9CgkJCgkJCgkJIyMjIyMjIyMjCglpZihpID09IDYpeyAjbmV3IGd1aW5lYSAgI3ZhbHVlcyBmcm9tIExhcnNvbgoJCQoJCWNvbXBsZXhfZmlndXJlKDQsICJOZXdfR3VpbmVhIiwgaSwgbWVhbnMsIHNkcykKCQkKCQl9CgoKIyMjIyMjIyMjCglpZihpID09IDcpeyAjRWFzdGVybiBOLkEuICAjdmFsdWVzIGZyb20gTGFyc29uCgkJCgkJY29tcGxleF9maWd1cmUoNSwgIkVfTm9ydGhfQW1lcmkiLCBpLCBtZWFucywgc2RzKQoJCQoJCQl9CgoKCQkjIyMjIyMjIyMKCWlmKGkgPT0gOCl7ICNBbmRlcyAgI3ZhbHVlcyBmcm9tIExhcnNvbgoJCQoJCWNvbXBsZXhfZmlndXJlKDYsICJDL1NfQW5kZXMiLCBpLCBtZWFucywgc2RzKQoJCQoJCQkJfQoKCiMjIyMjIyMjIwoJaWYoaSA9PSA5KXsgI1cuIEFmcmljYW4gU2F2ICAjdmFsdWVzIGZyb20gTGFyc29uCgkJCgkJY29tcGxleF9maWd1cmUoMSwgIldfQWZyaWNhbl9TYXYiLCBpLCBtZWFucywgc2RzKQoJCQoJCQl9CgoKIyMjIyMjIyMjCglpZihpID09IDEwKXsgI1N1ZGFuaWMgc2F2ICAjdmFsdWVzIGZyb20gTGFyc29uCgkJCgkJY29tcGxleF9maWd1cmUoMSwgIlN1ZGFuaWNfU2F2YW4iLCBpLCBtZWFucywgc2RzKQoJCQoJCQkJfQoKCiMjIyMjIyMjIwoJaWYoaSA9PSAxMSl7ICNHYW5nZXMgICN2YWx1ZXMgZnJvbSBMYXJzb24KCQkKCQkKCQljb21wbGV4X2ZpZ3VyZSg3LCAiR2FuZ2VzX0VfSW5kaSIsIGksIG1lYW5zLCBzZHMpIAoJCQoJCX0KCgojIyMjIyMjIyMKCWlmKGkgPT0gMTIpeyAjIkxvd2VyLU1pZGRsZVkiICAjdmFsdWVzIGZyb20gTGFyc29uCgkJCgkJY29tcGxleF9maWd1cmUoMiwgIkxvd2VyLU1pZGRsZVkiLCBpLCBtZWFucywgc2RzKQoJCSAKCQkgCQl9CgoJCQoJCQoJCSNsaW5lcyg0OjIxLCBtZWFuc1tbaV1dKQoJCQoJCSNhYmxpbmUoaCA9IDEsIGNvbD1hZGp1c3Rjb2xvcigiZm9yZXN0Z3JlZW4iLCBhbHBoYT0uNSksIGx0eT0yKQoJCQoJIyBhZGQgYXhlcyB0byBzb21lIGxvY2F0aW9ucwoJaWYoaSA9PSAxIHwgaSA9PSA3KXtheGlzKDIsIGF0PXNlcSgtMiwyLCBieT0wLjUpLCBsYWJlbD1zZXEoLTIsMiwgYnk9MC41KSwgbGFzPTEpfQoJaWYoaSA9PSA2IHwgaSA9PSAxMil7YXhpcyg0LCBhdD1zZXEoLTIsMiwgYnk9MC41KSwgbGFiZWw9c2VxKC0yLDIsIGJ5PTAuNSksIGxhcz0xKX0KCSNpZihpID09IDYgfCBpID09IDEyKXtheGlzKDQsIGF0PXNlcSgyLDMsIGJ5PTAuMjUpLCBsYWJlbD1zZXEoMCwxLCBieT0wLjI1KSwgbGFzPTEpCgkjCWF4aXMoNCwgYXQ9c2VxKC0xLDAsIGJ5PTAuMjUpLCBsYWJlbD1yZXYoc2VxKDAsMSwgYnk9MC4yNSkpLCBsYXM9MSkKCSMJfQoJaWYoaSA+IDYpe2F4aXMoMSl9IGVsc2V7YXhpcygzKX0KCgkKCSMgYWRkIHRleHQgCglpZihpIDwgNyl7cG9seWdvbih4PWMoLTMwLCAtMzAsIDMwLCAzMCksIHk9YygtMy4xLCAtMy41LCAtMy41LCAtMy4xKSwgY29sPSJibGFjayIpCgltdGV4dChuYW1lX3ZlY3RvcltpXSwgMSwgbGluZT0tMC45LCBjb2w9IndoaXRlIiwgY2V4PTAuNSl9CgkKCWlmKGkgPiA2KXtwb2x5Z29uKHg9YygtMzAsIC0zMCwgMzAsIDMwKSwgeT1jKDIuMSwgMi41LCAyLjUsIDIuMSksIGNvbD0iYmxhY2siKQoJbXRleHQobmFtZV92ZWN0b3JbaV0sIDMsIGxpbmU9LTAuOCwgY29sPSJ3aGl0ZSIsIGNleD0wLjUpfQoJCgkjIGFkZCBheGlzIGxhYmVscwoJaWYoaSA9PSAxIHwgaSA9PSAgNyl7bXRleHQoInNjYWxlZCBkZW5zaXR5IHBvdGVudGlhbCIsIDIsIGxpbmU9NCwgYXQ9MSl9CglpZihpID09ICAzKXttdGV4dCgiVGhvdXNhbmQgeWVhcnMgYmVmb3JlIHByZXNlbnQiLCAzLCBsaW5lPTMuNSwgYXQgPTUpfQoJaWYoaSA9PSAgOSl7bXRleHQoIlRob3VzYW5kIHllYXJzIGJlZm9yZSBwcmVzZW50IiwgMSwgbGluZT0zLjUsIGF0ID01KQoJCQoJCX0KCQp9CgoKCgoKCnNhdmVUb1BERiA8LSBmdW5jdGlvbiguLi4pIHsKICAgIGQgPSBkZXYuY29weShwZGYsLi4uKQogICAgZGV2Lm9mZihkKQp9CgpzYXZlVG9QTkcgPC0gZnVuY3Rpb24oLi4uKSB7CiAgICBkID0gZGV2LmNvcHkocG5nLC4uLikKICAgIGRldi5vZmYoZCkKfQoKIyMgVHJ5IHRoZW0gb3V0CgpzYXZlVG9QREYoIm15LnBkZiIsIGhlaWdodD04LHdpZHRoPTgpCnNhdmVUb1BORygibXkucG5nIiwgaGVpZ2h0PTgsIHdpZHRoPTgsIHVuaXRzPSJpbiIsIHJlcz0zMDApCmRldi5vZmYoKQoKCgpgYGAKCg==